zoukankan      html  css  js  c++  java
  • 进程 >> 互斥锁、队列与管道、生产者消费者模型

    1.互斥锁

    • 首先导入Lock模块
    • 实例化一把锁
    • 但是每次生成子进程的时候都会重新实例化一把锁,我们的目的是想让所有的子进程使用同一把锁,所以需要把锁传递给子进程在使用 锁名.acquire():开锁->所有子进程开始抢位置 锁名.release():关锁->位置排好了,开始执锁起来执行.
    • join与互斥锁的区别:join是把所有的子进程代码变为串行的,而互斥锁则可以规定那几行代码变为串行
    from multiprocessing import Process,Lock
    import time
    
    def foo(user,lock_new):
        lock_new.acquire()
        print(f"{user}--1")
        time.sleep(1)
        print(f"{user}--2")
        time.sleep(1)
        print(f"{user}--3")
        lock_new.release()
    
    if __name__ == '__main__':
        lock_new = Lock()
        for i in range(1,4):
            p = Process(target=foo, args=(i,lock_new))
            p.start()
    

    2.队列与管道

    • 互斥锁是基于硬盘资源的
    • 队列和管道是基于内存的,multiprocessing模块提供了这个处理操作,也就是IPC,基于网络间进程通信的方式
    • 队列是管道和锁的结合
    • 队列需要遵守先进先出算法
    • 还有就是就算不控制队列大小,他之后也会往里面塞数据
    • 队列里面是放小数据的,不可以放类似视频的这种大数据
    from multiprocessing import Queue
    
    q = Queue(3)
    q.put(1)
    q.put(2)
    q.put(3)
    print(q.full())
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.empty())
    

    3.生产者消费者模型(Queue)

    * 生产者消费者模型是根据队列来实现的
    * 生产者把产生的消费者所需要的数据放入队列中,消费者再去队列中取出来
    * 这一个知识点其实是队列的应用方式
    
    from multiprocessing import Process, Queue
    
    
    def producer(pro_name, q):  # 生产者
        for i in range(1,4):
            res = f"{pro_name}生产的第{i}个蛋"
            time.sleep(2)
            print(res)
            q.put(res)
    
    
    def consumer(con_name, q):
        while True: # 必须得死循环,因为你不知道生产者会生产多少东西,这个时候进程间通讯就起到很重要的作用
            res = q.get()
            if res is None:
                break
            print(f"{con_name}吃{res}")
    
    
    if __name__ == '__main__':
        q = Queue()
        p1 = Process(target=producer,args=("xc",q))
        c1 = Process(target=consumer,args=("wr",q))
        p1.start()
        c1.start()
        p1.join()
        q.put(None) # 在生产者结束生产之后,再传一个空值,因为消费者处于一直等待的状态,必须使用结束语句
        c1.join()
        print("打烊了")
    

    4.生产者消费者模型(JoinableQueue)

    from multiprocessing import Process,JoinableQueue
    import time
    
    def producer(pro_name, q):  # 生产者
        for i in range(3):
            print(f"{pro_name}做的第{i+1}个包子")
            res = f"{pro_name}做的第{i+1}个包子"
            q.put(res)
        # q.join() # 接受消费者取值的信号
    def consumer(con_name, q):
        while True:
            res = q.get()
            print(f"{con_name}吃了{res}")
            q.task_done()  # 发送消费者取值的信号,消费者把管道里面的数据取完了之后,生产者里面的join才会结束运行
            # 这个其实就是这个数据要是接收完毕,就会给发送数据的一个消息,发送数据就可以执行完毕
    
    if __name__ == '__main__':
        q = JoinableQueue() # 这个方法 也就是可以join的 (也就是等待包含task_done的语句数据接收完,而不是执行完的时候)
        p1 = Process(target=producer,args=('xc',q))
        p2 = Process(target=producer,args=('xxc',q))
        c1 = Process(target=consumer,args=('小狗',q))
        c1.daemon = True # 因为本身消费者语句虽然接收完数据了,但是还是再运行,可是已经没有数据可以接受了,所以我们定义守护进程,让他伴随主进程结束而结束
        p1.start()
        p2.start()
        c1.start()
        p1.join()
        p2.join()
        q.join() # 写再这里和卸载生产者语句里面是一样的
        print("打烊了")
    
  • 相关阅读:
    SQL SERVER2005中将普通表修改为分区表
    手把手教你建立SQL数据库的表分区
    捕获input 文本框内容改变的事件(onchange,onblur,onPropertyChange比较)
    sql语句求排名
    带输出参数的插入语句
    js Base64.encode(str)_decode(str).html
    jquery.base64.js(完美解决中文乱码) 免费版
    sql数据库如何获取某个字段里的最大值?
    C#里封装 继承 多态
    C#中的属性get和set()方法
  • 原文地址:https://www.cnblogs.com/xiongchao0823/p/11527617.html
Copyright © 2011-2022 走看看