• 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生产者消费者模型
  • 相关阅读:
    Electron-Builder 打包Nsis,安装后自动运行程序
    依赖倒置原则(DIP)、控制反转(IoC)、依赖注入(DI)(C#)
    六大设计原则(C#)
    C#简单爬取数据(.NET使用HTML解析器NSoup和正则两种方式匹配数据)
    简单架构:反射实现抽象工厂+IDAL接口完全独立DAL
    C#高级语法之泛型、泛型约束,类型安全、逆变和协变(思想原理)
    委托和lambda表达式,Action和Func
    .NET中使用WebService,以及和一般处理程序、类库的区别
    C#原型模式(深拷贝、浅拷贝)
    Thread、ThreadPool、Task、Parallel的基本用法、区别以及弊端
  • 原文地址:https://www.cnblogs.com/knighterrant/p/10038839.html
Copyright © 2020-2023  润新知