day31 锁 队列 前面课程重点总结
今日内容:
1.进程的其他方法
2.僵尸进程和孤儿进程(了解)
3.验证进程之间是空间隔离的
4.守护进程
5.进程锁 重点(又叫同步锁,互斥锁)
6.进程队列(重点) Queue
7.生产者消费者模型
8.管道,进程的数据共享,信号量,事件(了解)
1.进程的其他方法
进程的ID import os
查看子进程的ID os.getpid()
查看子进程的父进程的id os.getppid()
进程名字,
p1=process(target=f1,)
print(p1.name)
查看进程是否活着,
p1.is_alive() # 查看进程是否还活着
发送结束进程的信号
p1.terminate() # 给操作系统发送一个结束进程的信号
2.僵尸进程和孤儿进程(了解)
僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
僵尸进程是有害的
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
孤儿进程是无害的.
3.验证进程之间是有空间隔离的
from multiprocessing import Process num=100 def f1():
global num
num=30
print('子进程中的num',num) if __name__=='__main__':
p=Process(target=f1,)
p.start()
p.join()
print('主进程中的num',num)
最后的结果为, 打印的子进程的num的值为:30 打印的主进程中的num的值为:100,因此我们可以判断出进程之间是存在空间隔离的.
4.守护进程
守护进程: 将f1 设置为守护进程后,如果主进程结束后,f1的进程不管运行到什么地方,都是直接结束的.
import time
from multiprocessing import Process def f1():
time.sleep(1)
print('我是f1') def f2():
time.sleep(2)
print('我是f2') if __name__=='__main__':
p1=Process(target=f1,)
p2=Process(target=f2,)
p1.daemon=True# 此处为设置守护进程,设置守护进程必须在执行start之间设置,
守护进程的意思是如果我主进程的代码运行结束,那么你这个守护进程不管运行到什么地方,都要直接结束
p1.start()
p2.start()
p2.join()# 等待p2执行完毕后在运行主进程
print('主进程结束')
开启一个不同的子进程来验证一下守护进程的结束只和主进程的代码运行结束有关系,而整个程序的结束需要主进程和普通的子进程的代码都运行结束才结束.
5.进程锁,又叫互斥锁,同步锁(重点)
语法:
from multiprocessing import Process,Lock
1)
def f1(loc):
loc.acquire() # 上锁,保证程序运行到这里只能有一个进程进入里面执行
要锁的内容......
loc.release() # 解锁 ,程序代码运行完毕,开锁后,剩下的程序才能能继续抢这把锁
if __name__=='__main__':
loc=Lock() # 创建进程锁
p=Process(target=f1,args=(loc,))
2)
def f1(loc):
wIth loc:
要锁的内容......
if __name__=='__main__':
loc=Lock() # 创建进程锁
p=Process(target=f1,args=(loc,))
# 互斥锁/进程锁/同步锁
# import json
import time
from multiprocessing import Process,Lock
def show_t(i):
with open('ticket','r',encoding='utf-8') as f:
ticket_data = f.read()
# print(ticket_data)
t_data = eval(ticket_data)
# print(t_data,type(t_data))
print('%s查询剩余票数为%s'%(i,t_data['count'])) def get_t(i,l1):
l1.acquire()
with open('ticket', 'r', encoding='utf-8') as f:
ticket_data = f.read()
# print(ticket_data)
t_data = eval(ticket_data)
# print(t_data,type(t_data))
# print('%s查询剩余票数为%s' % (i, t_data['count']))
if t_data['count'] > 0:
t_data['count'] -= 1
print('%s抢票成功'%i)
time.sleep(0.2)
with open('ticket', 'w') as f:
f.write(str(t_data))
else:
print('没票了!!!')
l1.release() if __name__ == '__main__':
l1 = Lock()
for i in range(10):
p1 = Process(target=show_t,args=(i,))
p1.start()
for i in range(10):
p2 = Process(target=get_t,args=(i,l1) )
p2.start()
6.进程队列(重点) Queue
from multiprocessing import Process
q=Queue(5) # 这个队列只能放5个进程
q.put() # 往进程队列中放数据,如果进程满了会等待
q.get()# 从进程队列中拿数据
q.qsize()# 查看进程中数据的个数
q.empty() # 查看进程是否是空的
q.full() # 查看进程是否是满的
q.get_nowait()# 不等待,但是报错 一般 用try 尝试使用
q.put_nowait()# 不等待,但是报错 一般 用try 尝试使用
7.生产者消费者模型
import time
from multiprocessing import Process,Queue # 生产者
def producer(q):
for i in range():
time.sleep(1)
s=f'大包子{i}号'
print('新鲜出炉的'+s) #消费者
def consumer(q):
while 1:
time.sleep(2)
baozi=q.get()
print(baozi+'被吃了') if __name__=='__main__':
q=Queue(10)
pro_obj=Process(target=producer,args=(q,))
con_obj=Process(target=consumer,args=(q,))
pro_obj.start()
con_obj.start()
精简SVIP版生产者消费者模型
import time
from multiprocessing import Process,Queue,JoinableQueue def producer(q):
for i in range(10):
time.sleep(1)
s=f'大包子{i}号'
print('新鲜出炉的'+s)
q.put(s)
q.join()# 等着task_done()信号的数量,和我put进去的数量相同时,才继续执行
print('所有的包子都生产完毕了') def consumer(q):
while 1:
time.sleep(2)
baozi=q.get()
print(baozi+'被吃了')
q.task_done() # 给队列发送一个去处的这个任务已经处理完毕的信号 if __name__=='__main__':
q=JoinableQueue(30) # 和Queue一样都是创建一个长度为30的队列
pro_obj=Process(target=producer,args=(q,))
con_obj=Process(target=consumer,args=(q,))
pro_obj.start()
con_obj.start()
pro_obj.join()# 等生产者把包子全部生产完之后在结束
print('主程序结束')
什么是阻塞IO模型
IO模型就是当程序遇到阻塞的时候,程序会阻塞在这个地方不继续向下执行,直到阻塞执行完成之后,才向下执行 #实例代码:
import socket ser=socket.socket()
ser.bind(('127.0.0.1',8000))
ser.listen()
while True:
#建立连接的时候会发生IO阻塞,如果没有建立连接,会一直阻塞在这里
conn.addr = ser.accept()
#接收和发送消息的时候也会发生IO阻塞,在数据量大的时候才能感觉出来
data = conn.recv(1024)
conn.send(xxx) conn.close()
什么是非阻塞IO模型(不推荐使用)
当程序遇到阻塞后,立即切换到下一步去执行下一步的代码,期间不会产生阻塞和时间等待 #实例代码:
import socket
ser=socket.socket()
ser.bind(('127.0.0.1',8000))
ser.listen()
#将下面的代码都变成了非阻塞IO模型,如果遇到IO阻塞后会出现BlockingIOError,在这里如果检测到这个错误,就是已经设置了IO非阻塞模型
ser.setblocking(False) clist=[]
wlist=[]
while True:
try:
#检测IO阻塞的错误
conn.addr = ser.accept()
#如果捕获到IO阻塞异常之后,就不会添加到这个列表中
clist.append(conn)
except BlockingIOError:
del_clist = []
#这个for循环做的事是专门收消息
for conn in clist:
try:
data = conn.recv(1024)
#如果没有拿到数据,就把它删除掉
if not data:
del_clist.append(conn)
continue
conn.send(发送的数据)
wlist.append((conn,发送的数据)) except BlockingIOError:
continue
except Exception:
conn.close()
del_clist.append(conn)
#专门发消息
del_wlist=[]
for msg in wlist:
try:
conn=msg[0]
data=msg[1]
conn.send(data)
del_wlist.append(msg)
except BlockingIOError:
pass
#将发送成功之后的那个元组从之前的列表中删除
for dd in del_wlist:
w_list.remove(dd)
#将发送完成之后关闭的套接字删除掉
for d in del_clist:
c_list.remove(d)
day31 锁 队列 前面课程重点总结的更多相关文章
- zeromq源码分析笔记之无锁队列ypipe_t(3)
在上一篇中说到了mailbox_t的底层实际上使用了管道ypipe_t来存储命令.而ypipe_t实质上是一个无锁队列,其底层使用了yqueue_t队列,ypipe_t是对yueue_t的再包装,所以 ...
- AQS学习(一)自旋锁原理介绍(为什么AQS底层使用自旋锁队列?)
1.什么是自旋锁? 自旋锁作为锁的一种,和互斥锁一样也是为了在并发环境下保护共享资源的一种锁机制.在任意时刻,只有一个执行单元能够获得锁. 互斥锁通常利用操作系统提供的线程阻塞/唤醒机制实现,在争用锁 ...
- 无锁队列以及ABA问题
队列是我们非常常用的数据结构,用来提供数据的写入和读取功能,而且通常在不同线程之间作为数据通信的桥梁.不过在将无锁队列的算法之前,需要先了解一下CAS(compare and swap)的原理.由于多 ...
- HashMap的原理与实 无锁队列的实现Java HashMap的死循环 red black tree
http://www.cnblogs.com/fornever/archive/2011/12/02/2270692.html https://zh.wikipedia.org/wiki/%E7%BA ...
- boost 无锁队列
一哥们翻译的boost的无锁队列的官方文档 原文地址:http://blog.csdn.net/great3779/article/details/8765103 Boost_1_53_0终于迎来了久 ...
- 一个可无限伸缩且无ABA问题的无锁队列
关于无锁队列,详细的介绍请参考陈硕先生的<无锁队列的实现>一文.然进一步,如何实现一个不限node数目即能够无限伸缩的无锁队列,即是本文的要旨. 无锁队列有两种实现形式,分别是数组与链表. ...
- 无锁队列--基于linuxkfifo实现
一直想写一个无锁队列,为了提高项目的背景效率. 有机会看到linux核心kfifo.h 原则. 所以这个实现自己仿照,眼下linux我们应该能够提供外部接口. #ifndef _NO_LOCK_QUE ...
- CAS简介和无锁队列的实现
Q:CAS的实现 A:gcc提供了两个函数 bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...)// ...
- Go语言无锁队列组件的实现 (chan/interface/select)
1. 背景 go代码中要实现异步很简单,go funcName(). 但是进程需要控制协程数量在合理范围内,对应大批量任务可以使用"协程池 + 无锁队列"实现. 2. golang ...
随机推荐
- MYSQL的常用函数(字符串函数)
ASCII(char)返回字符的ASCII码值 BIT_LENGTH(str)返回字符串的比特长度 CONCAT(s1,s2...,sn)将s1,s2...,sn连接成字符串 CONCAT_WS(se ...
- (转)C# Where关键词的用法
where(泛型类型约束) where关键词一个最重要的用法就是在泛型的声明.定义中做出约束. 约束又分为接口约束.基类约束.构造函数约束.函数方法的约束,我们慢慢介绍. 接口约束 顾名思义,泛型参数 ...
- socket 发送图片
using System;using System.Collections.Generic;using System.Text;using System.Net.Sockets;using Syste ...
- 雷林鹏分享:jQuery EasyUI 树形菜单 - 树形菜单添加节点
jQuery EasyUI 树形菜单 - 树形菜单添加节点 本教程向您展示如何附加节点到树形菜单(Tree).我们将创建一个包含水果和蔬菜节点的食品树,然后添加一些其他水果到已存在的水果节点. 创建食 ...
- 雷林鹏分享:C# 数组(Array)
C# 数组(Array) 数组是一个存储相同类型元素的固定大小的顺序集合.数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合. 声明数组变量并不是声明 number0.number1... ...
- for...in和for...of循环的区别
使用for...in和for...of分别对Array,Set,Map做测试 var a=["A","B","C"]; var b=new ...
- Configuring Groovy SDK within IntelliJ IDEA
一.原因 IntelliJ IDEA期待一个the standard Groovy SDK 二.解决方案: 下载安装Groovy就可以了 官网下载地址: http://groovy-lang ...
- Confluence 6 指派和撤销空间权限
指派空间权限 希望添加一个新用户或者用户组到权限列表中,从希望选择的选项中查找用户组或者用户,然后选择 添加(Add).用户和用户组将会显示在列表中:选择你希望引用的权限,然后选择 保存所有(Save ...
- jq 倒计时
引入jq 注 在IE和safari 如果时间出现NAN 将时间格式改为YYYY/MM/DD HH:MM:SS 例:var d2 = new Date("2019/02/18 15:59&qu ...
- 2.2 UML用例模型
参与者(Actor) 参与者(注:有另一种翻译“执行者”) 代表位于系统之外并和系统进行交互的一类事物(人.物.其他软件子系统等) 通过它,可以对软件系统与外界发生的交互进行分析和描述 通过它,可以了 ...