• 守护进程,互斥锁,IPC进程间通信,生产者消费者模型


    守护进程
    '''
    1、守护进程
    守护进程其实就是一个“子进程”
    守护=》伴随
    守护进程会伴随主进程的代码运行完毕后而死掉

    2、为何用守护进程
    关键字就两个:
    进程:
    当父进程需要将一个任务并发出去执行,需要将该任务放到一个子进程里
    守护:
    当该子进程内的代码在父进程代码运行完毕后就没有存在的意义了,就应该
    将该子进程设置为守护进程,会在父进程代码结束后死掉
    '''

    from multiprocessing import Process
    import time
    def task(name):
        print("%s is running" %name)
        time.sleep(3)
    
    if __name__ == '__main__':
        p1 = Process(target=task,args=("守护进程",))
        p2 = Process(target=task,args=("正常的子进程",))
    
        p1.daemon= True#要放在p.start()之前,并且只要是守护进程都不会打印内容
        p1.start()
        p2.start()
        print("")#主进程结束之后,守护进程就已经结束
    from multiprocessing import Process
    import time
    def foo():
        print(123)
        time.sleep(1)
        print("end123")
    
    def bar():
        print(456)
        time.sleep(3)
        print("end456")
    
    if __name__ == '__main__':
        p1=Process(target=foo)
        p2=Process(target=bar)
    
        p1.daemon=True
        p1.start()
        p2.start()
        print("main-------")
    主进程代码运行完毕,守护进程就会结束

    互斥锁
    #互斥锁:可以将要执行任务的部分代码(只涉及到修改共享数据的代码)变成串行
    #join:是要执行任务的所有代码整体串行

    from multiprocessing import Process,Lock
    import json
    import os
    import time
    import random
    
    def check():
        time.sleep(1)#模拟网路延迟
        with open("db.txt","rt",encoding="utf-8") as f:
            dic = json.load(f)
        print("%s 查看到生于票数[%s]" %(os.getpid(),dic["count"]))
        #显示哪个id看到的票数
    
    def get():
        with open("db.txt","rt",encoding="utf-8") as f:
            dic = json.load(f)
        time.sleep(random.randint(1,3))
        if dic["count"] > 0:
            #有票
            dic["count"]-=1
            time.sleep(random.randint(1,3))
            with open("db.txt","wt",encoding="utf-8") as f:
                json.dump(dic,f)#以json模块进行存储
            print("%s 购票成功" %os.getpid())
        else:
            print("%s 没有余票" %os.getpid())
    
    def task(mutex):
        #查票
        check()
        #购票
        mutex.acquire()#互斥锁不能连续锁acquire(获得上锁),必须是release(放解锁)以后
        # 才能重新acquire,锁需要在想要上锁的函数正上方输入mutex.acquire(),然后再想要
        # 解锁的位置输入mutex.release()
        # 简洁写法再函数上方with mutex:
        # with mutex:
        #     get()#只锁了get,其他并没有锁
        # check()#购票后的查看都是随机时间查看,没有规定必须谁先出来谁可以查看
        # check()
        # check()
        get()
        mutex.release()
    if __name__ == '__main__':
        mutex = Lock()#互斥锁要在main下方
        for i in range(10):
            p=Process(target = task,args = (mutex,))
            p.start()
    互斥锁

    IPC进程间通信,两种方式
    IPC:进程间通信,有两种实现方式
    1、pipe:
    2、queue:pipe+锁

    # q=Queue(3)#设置队列最大存放数,先进先出
    # #注意:
    # #1、队列占用的是内存空间
    # #2、不应该往队列中放大数据,应该只存放数据量较小的信息
    # #掌握的
    # q.put('first')
    # q.put({'k':'sencond'})
    # q.put(['third',])
    # #当超过队列最大存放数时会堵塞,默认会进入等待,等待前面的被取走,然后再进
    # q.put(4)
    #
    # print(q.get())
    # print(q.get())
    # print(q.get())
    # #超过队列最大取出数时会堵塞,默认会进入等待,等待前面有新放入,然后取出
    # print(q.get())
    # print(q.get(block=True,timeout=4))
    # q=Queue(3)
    # q.put('first')
    # q.put({'k':'sencond'})
    # q.put(['third',])
    # #默认的block为True,如果将block改为False,造成队列堵塞时会直接报错,
    # # 如果block为True,timeout为计时秒数,超过等待秒数会报错
    # q.put(4,block=True,timeout=3)
    #
    # print(q.get())
    # print(q.get())
    # print(q.get())
    
    
    
    q=Queue(3)
    q.put('first')
    q.put({'k':'sencond'})
    q.put(['third',])
    
    print(q.get())
    print(q.get())
    print(q.get())
    #默认的block为True,如果将block改为False,队列中没东西取出会自动报错,
    # 如果block为True,timeout为计时秒数,超过等待秒数会报错
    print(q.get(block=True,timeout=None))
    了解

    生产者消费者模型:
    '''
    1 什么是生产者消费者模型
    生产者:比喻的是程序中负责产生数据的任务
    消费者:比喻的是程序中负责处理数据的任务

    生产者->共享的介质(队列)<-消费者

    2 为何用
    实现了生产者与消费者的解耦和,生产者可以不停地生产,消费者也可以不停地消费
    从而平衡了生产者的生产能力与消费者消费能力,提升了程序整体运行的效率

    什么时候用?
    当我们的程序中存在明显的两类任务,一类负责产生数据,另外一类负责处理数据
    此时就应该考虑使用生产者消费者模型来提升程序的效率

    '''

    from multiprocessing import Queue,Process
    import time,os,random
    def producer(q):
        for i in range(10):#循环每次的数值
            res="包子%s" %i
            time.sleep(random.randint(1,3))
            q.put(res)#将制作好的东西放入到队列中
            print("%s 生产了%s" %(os.getpid(),res))
        q.put(None)
    
    def consumer(q):
        while True:
            res=q.get()#循环从队列中取出内容
            if res is None:break
            time.sleep(random.randint(1,3))
            print("%s 吃了 %s" %(os.getpid(),res))
    
    if __name__ == '__main__':
        q=Queue()
        p1=Process(target=producer,args=(q,))
        c1=Process(target=consumer,args=(q,))
        p1.start()
        c1.start()
        print("")
    方式一
    from multiprocessing import Queue,Process
    import time,random,os
    def produce(name,food,q):
        for i in range(3):
            res = "%s %s" %(food,i)
            time.sleep(random.randint(1,3))
            q.put(res)
            print("%s 生产了 %s" %(name,food))
    
    def consumer(name,q):
        while True:
            res = q.get()
            if res is None:break
            time.sleep(random.randint(1,3))
            print("%s 吃了 %s" %(name,res))
    
    if __name__ == '__main__':
        q=Queue()
        p1 = Process(target=produce,args=("egon","包子",q))
        p2 = Process(target=produce,args=("hm","汉堡",q))
        p3 = Process(target=produce,args=("张飞","鹿腿",q))
    
        c1 = Process(target=consumer,args=("fxc",q))
        c2 = Process(target=consumer,args=("cc",q))
    
        p1.start()
        p2.start()
        p3.start()
    
        c1.start()
        c2.start()
    
        p1.join()
        p2.join()
        p3.join()
        # 在p1p2p3都结束后,才应该往队列里放结束信号,有几个消费者就应该放几个None
        q.put(None)
        q.put(None)
    
        print("")
    方式二:修改版
    from multiprocessing import JoinableQueue,Process#JoinableQueue是将队列取空
    import time,random
    
    def producer(name,food,q):
        for i in range(3):
            res = "%s%s" %(food,i)
            time.sleep(random.randint(1,3))
            q.put(res)
            print("%s 生产了 %s" %(name,res))
    
    def consumer(name,q):
        while True:
            res = q.get()
            if res is None:break
            time.sleep(random.randint(1,3))
            print("%s 吃了 %s" %(name,res))
            q.task_done()#队列里面每取出一个就-1
    
    if __name__ == '__main__':
        q=JoinableQueue()
        p1=Process(target=producer,args=("egon","包子",q))
        p2=Process(target=producer,args=("hm","汉堡",q))
        p3=Process(target=producer,args=("张飞","鹿腿",q))
    
        c1=Process(target=consumer,args=("fxc",q))
        c2=Process(target=consumer,args=("cc",q))
        c1.daemon=True
        c2.daemon=True
    
        p1.start()
        p2.start()
        p3.start()
        c1.start()
        c2.start()
    
        p1.join()
        p2.join()
        p3.join()
    
        q.join()#等待列队内被取干净
        # 主进程的代码运行完毕--->(生产者运行完毕)+队列中的数据也被取干净了->消费者没有存在的意义
    方式三:最终版
  • 相关阅读:
    网页的状态掩码
    分享到JavaScript
    右下角收缩广告
    播放列表的收缩展开
    创建文本节点createTextNode
    创建元素节点createElement
    进栈和出栈
    刚刚上班才回来,今天和你说说hash数组
    关于JS中的定时器!!!
    面向对象(程序员最呆的地方,一切皆是对象)
  • 原文地址:https://www.cnblogs.com/yf18767106368/p/9301577.html
Copyright © 2020-2023  润新知