zoukankan      html  css  js  c++  java
  • Python3 三种Queue的异同

    一、Queue(队列)

    Queue是python中的标准库,可以直接import 引用,队列默认遵循先进先出原则。

    import queue
    q = queue.Queue(10)
    # 向队列中添加元素
    q.put('yang')
    q.put(4)
    q.put(['yan', 'xing'])
    
    # 从队列中取出元素,默认的队列是先进先出的
    q.get()
    # 'yang'
    q.get()
    # 4
    q.get()
    # ['yan', 'xing']
    

    当一个队列为空的时候如果再用get取则会堵塞,所以取队列的时候一般是用到get_nowait()方法,这种方法在向一个空队列取值的时候会抛一个Empty异常,所以更常用的方法是先判断一个队列是否为空,如果不为空则取值。

    队列中常用的方法
    Queue.qsize() 返回队列的大小  
    Queue.empty() 如果队列为空,返回True,反之False  
    Queue.full() 如果队列满了,返回True,反之False 
    Queue.get([block[, timeout]]) 获取队列,timeout等待时间  
    Queue.get_nowait() 相当Queue.get(False) 
    

    非阻塞 Queue.put(item) 写入队列,timeout等待时间
    Queue.put_nowait(item) 相当Queue.put(item, False)

    二、multiprocessing中的Queue

    multiprocessing中的Queue是多进程间进行通信的消息队列。

    from multiprocessing import Process,Queue
    import os,time,random
    
    #写数据进程执行的代码:
    def write(p):
        for value in ['A','B','C']:
            print ('Write---Before Put value---Put %s to queue...' % value)
            p.put(value)
            print ('Write---After Put value')
            time.sleep(random.random())
            print ('Write---After sleep')
    
    #读数据进程执行的代码:
    def read(p):
        while True:
            print ('Read---Before get value')
            value = p.get(True)
            print ('Read---After get value---Get %s from queue.' % value)
    
    if __name__ == '__main__':
        #父进程创建Queue,并传给各个子进程:
        p = Queue()
        pw = Process(target=write,args=(p,))
        pr = Process(target=read,args=(p,))
        #启动子进程pw,写入:
        pw.start()
        #启动子进程pr,读取:
        pr.start()
        #等待pw结束:
        pw.join()
        #pr进程里是死循环,无法等待其结束,只能强行终止:
        pr.terminate()
    

    三、multiprocessing.Manager.Queue

    如果把上面的代码改成下面的样子:

    if __name__=='__main__':    
        # 父进程创建Queue,并传给各个子进程:
        q = Queue()
        p = Pool()
        pw = p.apply_async(write,args=(q,))    
        pr = p.apply_async(read,args=(q,))
        p.close()
        p.join()
    

    本意是将会得到一个队列,将其作为参数传入进程池子里的每个子进程,但是却得到报错:RuntimeError: Queue objects should only be shared between processes through inheritance。

    大意是:队列对象不能在父子进程间通信。如果想要在进程池中使用队列,则要使用multiprocessing的Mananger类:

    if __name__=='__main__':
        manager = multiprocessing.Manager()
        # 父进程创建Queue,并传给各个子进程:
        q = manager.Queue()
        p = Pool()
        pw = p.apply_async(write,args=(q,))
        time.sleep(0.5)
        pr = p.apply_async(read,args=(q,))
        p.close()
        p.join()
    

    这样这个队列对象就可以在父进程与子进程间通信,不用池则不需要Manager。

    总结

    queue.Queue 是进程内非阻塞队列
    multiprocess.Queue 是跨进程通信队列
    前者是各自进程私有, 后者是各子进程共有
    Manager.Queue和 Queue,multiprocessing.Queue本质上没有太大关系,但它们有相同的方法。

  • 相关阅读:
    Nginx进程信号管理
    Nginx配置缓存服务器
    访问Nginx显示目录
    kubeadm快速安装k8s
    《构建之法》读书笔记(一)
    Android Studio连接SQLite数据库与SQLite Studio实时同步的实现
    关于sqlite数据库与sqlite studio
    AS之去掉顶部标题栏
    今日学习
    AS之AlertDialog使用
  • 原文地址:https://www.cnblogs.com/remixnameless/p/13452662.html
Copyright © 2011-2022 走看看