• python学习笔记 day36 队列(IPC机制----进程之间互相通信)


    1. 队列

    从multiprocessing模块导入的队列Queue跟其他队列一样也具有put()方法,get()方法,qsize()方法:

    创建队列的第一种方式:(无参数---可以往队列中无限制的放值):

    from multiprocessing import Queue
    q=Queue()  # 实例化一个队列,无参数,长度不限制,可以往队列中无限制的放值
    q.put(1)   # 往队列中放值
    q.put(2)
    print("此时队列的长度:",q.qsize())  # 查看当前队列的长度
    print(q.get())  # 从队列中取值
    print(q.get())
    # print(q.get())  # 由于此时队列中只有两个值,所以第三次再进行取值时就会发生阻塞,会一直等着队列中有值

    运行结果:

     创建队列的第二种方式---(有参数,只可以往队列中放入指定长度的元素,超出限制,就会发生阻塞,除非队列中有元素被取出来,才可以继续往队列中放值)

    from multiprocessing import Queue
    q=Queue(4)  # 实例化一个队列,有参数,长度有限制,只可以往队列中放四个值,超出限制就会发生阻塞,除非队列中的元素被取出来
    q.put(1)   # 往队列中放值
    q.put(2)
    q.put(3)
    q.put(4)
    print("此时队列的长度:",q.qsize())  # 查看当前队列的长度
    print(q.get())  # 从队列中取值
    q.put(5) # ,如果已经放满了四个值,再试图放第五个值就会发生阻塞 ,除非从队列中取值,才可以继续放
    print(q.get())  # 从队列中取值
    print(q.get())
    print(q.get())
    print(q.get())
    
    

    运行结果:

    之前说过进程与进程之间的资源是不能互相共享的,但是使用multiprocessing 模块的的Queue可以实现子进程与主进程之间的通信,子进程与子进程之间的互相通信;

    1. 实现子进程与主进程之间的通信:

    from multiprocessing import Queue
    from multiprocessing import Process
    
    def q_put(q):
        q.put("hello,xuanxuan")  # 往队列中插入元素
    
    if __name__=="__main__":
        q=Queue() # 实例化i一个队列
        p=Process(target=q_put,args=(q,))  # 创建一个子进程来执行q_put()往队列放元素
        p.start()
        print(q.get())  # 在主进程中执行q.get()可以对元素取值 这样就实现了主进程和子进程之间的通信

    运行结果:

    2.实现子进程之间的互相通信:

    from multiprocessing import Queue
    from multiprocessing import Process
    def q_put(q):
        q.put("hello,璇璇")  # 会开一个子进程执行往队列中放值的操作
    
    def q_get(q):
        print(q.get())  # 会开一个新的子进程执行从队列中取值的操作
    
    if __name__=="__main__":
        """
        使用Queue实现子进程与子进程之间的通信
        """
        q = Queue()  # 实例化一个队列
        p = Process(target=q_put, args=(q,))
        p.start()
        p2 = Process(target=q_get, args=(q,))
        p2.start()

    运行结果:

    总结:

    1. 有两种方式可以创建队列,一种无参数,不限长度,可以往队列中无限制的放很多很多元素;另一种有参数,只能往队列中放入指定长度的元素,超出限制,就会发生阻塞,只能等待从队列中把元素取出来;

    2. 队列有put()方法(往队列中放入元素)get()方法(从队列中取值),qsize()方法(查看当前队列的长度)----异步时有可能不太准;

    3. 通过队列可以实现子进程与主进程之间的互相通信;可以实现子进程子进程之间的互相通信;

    2. 生产者消费者模型

     之前在同步编程中,有时候会生产一个数据,然后给一个函数,让函数依赖这个数据进行运算,拿到结果-----同步过程;但是这种方式在生产数据和消费数据速度不匹配时(比如生产数据的速度极快,但是消费处理数据的速度很慢),速度不匹配,就会出现等待,,效率很低;

    我们可以使用异步并发编程,开多个进程来协调生产者和消费者速度不匹配的情况(比如生产速度快,但是消费速度慢,我们就可以开多个进程执行消费者完成的事情,如果是生产速度慢,但是消费速度快,就可以开多个进程执行生产)这样就可以解决生产消费速度不匹配的问题,然后执行速度快的先把执行结果,放入队列Queue(multiprocessing模块的Queue)

    from multiprocessing import Queue
    from multiprocessing import Process
    import time
    def producer(q):  # 生产者模型,可以同时生产很多数据
        for i in range(50):
            q.put(i)
    def consumer(q):
        for i in  range(50):
            time.sleep(1)  # 模拟消费者速度慢
            print("消费:%s"%q.get())
    
    if __name__=="__main__":
        q=Queue(10) # 实例化一个队列,有参数,表明队列的长度10 ,最多队列里面只能存放10个元素(节省内存,不要把所有的数据一下子全放在内存)
        p=Process(target=producer,args=(q,))   # 开一个进程执行producer()函数,不断生产数据:不断往队列中放数据(但是最多只能放入10个数据,除非消费者从队列中取值,才可以继续放队列中放值)
        p.start()
        c1=Process(target=consumer,args=(q,))  # 另外开一个进程,执行consumer()函数,不断从队列中取值,但是消费的速度慢(sleep(1))所以其实我们可以开多个进行执行consumer()
        c1.start()
        c2=Process(target=consumer,args=(q,))  # 由于消费者速度慢,所以为了解决生产消费速度不匹配的情况,可以开多个子进程执行consumer()函数
        c2.start()

    运行结果:

     对于内存来说,每次只有很少的数据在内存中;

    对于生产消费之间的不平衡来说,增加消费或者增加生产来调节效率

    talk is cheap,show me the code
  • 相关阅读:
    《MobileNetV2: Inverted Residuals and Linear Bottlenecks》论文阅读
    CF1464D The Thorny Path
    Codeforces Global Round #12
    欧拉数 (Eulerian Number)
    CF1437F Emotional Fishermen
    CF1408G Clusterization Counting
    [PA2013] Filary
    Codeforces Educational Round #95 题解
    [清华集训2016] 你的生命已如风中残烛
    [题解] lxxx
  • 原文地址:https://www.cnblogs.com/xuanxuanlove/p/9778849.html
Copyright © 2020-2023  润新知