python记录_day31 进程同步和进程通信
一、进程同步
1、同步锁(又叫互斥锁)
加锁的代码以后,同一时间内只能被一个进程执行
1 from multiprocessing import Process, Lock 2 3 def fun(loc): 4 5 loc.acquire() #加锁 6 pass #这里的代码只能被一个进程执行 7 loc.release() #释放锁 8 9 10 if __name__ =="__mian__": 11 12 loc = Locke() #创建锁对象 13 p = Process(target=fun,args=(loc,)) 14 p.start()
2、信号量
信号量相当于有多把钥匙的锁。同一时间允许多个进程执行加锁的代码
信号量中有一个计数器,进来一个进程计数器+1,出去一个进程计数器-1
1 from multiprocessing import Process, Semaphore 2 3 def fun(): 4 5 s.acquire() #信号量中计数器+1 6 pass #这里的代码最多能被4个进程同时执行 7 s.release() #信号量中计数器-1 8 9 if __name__ =="__main__": 10 s = Semaphore(4) 11 p = Process(target=fun,args=(m,)) 12 p.start()
3、事件
e = Event() 创建一个事件对象,有两个状态,True和False,默认是False
e.wait() 事件状态为false时等待
e.set() 将事件状态设置为True
e.clear() 将事件状态改为False
二、进程通信
1、守护进程
将一个进程设置为守护进程: p.daemon = True
# 正常情况下,子进程和主进程异步执行,所以子进程的执行不会受主进程状态的影响,但设为守护进程后,守护进程会随着主进程代码的结束而结束。
# 主进程代码结束不意味着主进程结束,主进程是要等子进程都结束才结束的,给子进程收尸。
# 如果一个子进程设置为了守护进程,它里面就不能再开子进程了。
2、队列
队列是进程安全的。因为它里边的数据取一次就没了,在进程通信时推荐使用。
q = Queue(n) 创建队列对象,能容纳 n 个元素
q.put() 往队列中添加数据,队列满时会等待
q.get() 从队列中取数据,队列空时会等待
q.full() 判断队列是否满了
q.empty() 判断队列是否为空
q.get_nowait() 或 q.get(False) 取数据时不等待
q.put_nowait() 或 q.put(False) 添加数据时不等待
3、生产者消费者模型
就是使用缓冲区将多个进程解耦
一般使用队列,一个进程往里放数据,一个进程取数据,也就是一个生产,一个消费
4、joinablequeue
升级版队列,比队列多了两个方法task_done和join,其他用法一样
q.task_done() 给队列发送一个信号
q.join() 队列接收一个信号
joinablequele相当于内部有一个计数器,put一个数据,计数器+1,然后取一个数据后用task_done()发一个信号,join接收信号,程序阻塞,当jion接收到和计数器相同的信号数量时结束阻塞。