31 锁,信号量,事件,队列


1.同步锁(互斥锁)
from mutilprocessing import Lock
方式一:
lock=Lock()
lock.acquire()
数据操作的代码
lock.release()
方式二:
with lock:
数据操作代码
2.信号量
from mutilprocessing import Semaphore
一把锁,多把钥匙
s=semaphore(n) #同一时间只有n个进程进入锁里的代码
s.acquire()
数据操作代码
s.release()

3.事件
from mutilprocessing import Event
e=Event() #默认
e.set()
e.clear()
e.wait()
e.is_set()
4.
队列 Queue 进程间通信 保证数据安全(同一个数据只有一个进程能拿到)
先进先出
q=Queue()
q.put()
q.get()
q.full()
q.empty()
q.get_nowait()
q.put_nowait()

Jionablequeue 和队列类似 多了两个方法 join() task_done()

守护进程 daemon

随着父进程结束,守护进程跟着结束
p.daemon=True #必须在p.start 前加
如何将一个子进程设置为守护进程,不能在该子进程中再开子进程

生产者和消费者模型:通过一个第三方(类似缓冲区)进行解耦
from multiprocessing import Process,Lock
import time

def show_ticket(i):
    with open("file","r",encoding="utf-8") as f:
        num=f.read().strip()
        print("%s客户查看到了剩余票数:"%i,num)

def func1(i,lock):
    show_ticket(i)
    print("准备开始抢票了")
    time.sleep(1)
    lock.acquire()
    with open("file","r",encoding="utf-") as f:
        num=f.read().strip()
        if num=="0":
            print("没票了")
        else:
            with open("file","w",encoding="utf-8") as f:
                num=int(num)
                num-=1
                f.write(str(num))
                print("%s客户抢到票了"%i)
    lock.release()


if __name__ == '__main__':
    lock=Lock()
    for i in range(10):
        p=Process(target=func1,args=(i,lock))
        p.start()
锁LOCK
from multiprocessing import Event,Process

e=Event()#两个状态  true false   默认为false
print("开始了")

print(e.is_set()) #查看事件当前的状态  #False

e.set() #将当前事件状态改为true

print(e.is_set())#true

e.clear() #将当前事件改为flase

e.wait()  #事件等待
print(e.is_set())
事件1
from multiprocessing import Process,Event
import time
def func1(e):
    time.sleep(2)
    print("子进程一大堆运算")
    e.set()  #将事件改为true



if __name__ == '__main__':
    e=Event()
    p=Process(target=func1,args=(e,))
    p.start()
    print("主进程开始程序")
    time.sleep(1)
    print("等待子进程通知")
    e.wait()
    print("拿到子进程通知,继续执行")
事件2Event
from multiprocessing import Process,Semaphore
import time

def func1(i,s):
    s.acquire()
    time.sleep(1)
    print("%s男嘉宾大保健开始"%i)
    time.sleep(0.5)
    print("%s大保健结束"%i)
    s.release()


if __name__ == '__main__':
    s=Semaphore(3) #信号量和lock类似,多了参数
    for i in range(10):
        p=Process(target=func1,args=(i,s))
        p.start()
信号量semaphore
from multiprocessing import Process,Queue

def func(q):
    ret=q.get()
    print(ret)

if __name__ == '__main__':

    q=Queue(5)   #队列是进程安全的
    q.put("hello gril")
    p=Process(target=func,args=(q,))
    p.start()
    print("主进程结束")

def func(q):
    ret=q.get()
    print(ret)


if __name__ == '__main__':
    q=Queue(3)
    q.put("约吗")

    p=Process(target=func,args=(q,))
    p.start()
    print("主进程结束")
基于队列进程通信Queue
from multiprocessing import Process
import os
import time
class Myprocess(Process):
    def __init__(self,person):
        super().__init__()
        self.person=person

    def run(self):
        print(os.getpid(),self.name)
        print("%s正在和女主播聊天"%self.person)

if __name__ == '__main__':

    p=Myprocess("刘德华")
    p.daemon=True  #一定要在p.start()之前设置p守护进程,禁止p创建子进程,并且父进程代码执行完毕,p将终止运行
    p.start()
    time.sleep(1)
    print("主进程结束")
守护进程daemon
from multiprocessing import Process,Queue
import time

def producer(q):
    for i in range(10):
        time.sleep(1)
        q.put("包子%s号"%i)
        print("包子%s号生产完毕"%i)
    q.put(None)

def consumer(q):
   while 1:
       baozi=q.get()
       if baozi==None:
         break
       time.sleep(1.5)
       print("%s被吃完"%baozi)



if __name__ == '__main__':
    q=Queue(10)
    p1=Process(target=producer,args=(q,))
    p2=Process(target=consumer,args=(q,))
    p1.start()
    p2.start()
生产者消费者模型
from multiprocessing import Process,JoinableQueue

import time,random,os

def producer(food,q):
    for i in range(10):
        time.sleep(random.random())
        ret="%s%s"%(food,i)
        q.put(ret)
        print("%s生产了%s"%(os.getpid(),ret))
    print("%s生产结束"%food)
    q.join() #生产完毕,使用此方法进行阻塞 ,直到队列中所有项目均被处理
    # print("%s生产结束" % food)

def consumer(q):
    while 1:
        ret=q.get()
        time.sleep(random.random())
        print("%s吃了%s"%(os.getpid(),ret))
        q.task_done()#向q.join()发送一次信号,证明一个数据被取走

if __name__ == '__main__':

    q=JoinableQueue()
    #生产者们
    p1=Process(target=producer,args=("包子",q,))
    p2=Process(target=producer,args=("玉米",q,))
    p3=Process(target=producer,args=("",q,))
    #消费者们
    c1=Process(target=consumer,args=(q,))
    c2=Process(target=consumer,args=(q,))
    c1.daemon=True
    c2.daemon=True
    #开始
    p_1=[p1,p2,p3,c1,c2]
    for p in p_1:
        p.start()
    p1.join()
    p2.join()
    p3.join()
JoinableQueue生产者消费者模型

 

posted @ 2018-11-29 15:53  冰底熊  阅读(182)  评论(0编辑  收藏  举报