zoukankan      html  css  js  c++  java
  • python核心高级学习总结4-------python实现进程通信

    Queue的使用

    Queue在数据结构中也接触过,在操作系统里面叫消息队列。
    使用示例
    # coding=utf-8
    from multiprocessing import Queue
    
    q = Queue(3)  # 初始化⼀个Queue对象, 最多可接收三条put消息
    q.put("消息1")
    q.put("消息2")
    print(q.full())  # False
    q.put("消息3")
    print(q.full())  # True
    
    # 因为消息列队已满下⾯的try都会抛出异常, 第⼀个try会等待2秒后再抛出异常, 第⼆个Try会⽴
    try:
        q.put("消息4", True, 2)
    except:
        print("消息列队已满, 现有消息数量:%s" % q.qsize())
    try:
        q.put_nowait("消息4")
    except:
        print("消息列队已满, 现有消息数量:%s" % q.qsize())
        # 推荐的⽅式, 先判断消息列队是否已满,再写⼊
    if not q.full():
        q.put_nowait("消息4")
    #读取消息时, 先判断消息列队是否为空, 再读取
    if not q.empty():
        for i in range(q.qsize()):
        print(q.get_nowait())
    
    运行结果
    False
    True
    消息列队已满, 现有消息数量:3
    消息列队已满, 现有消息数量:3
    消息1
    消息2
    消息3
    注意:若Queue()没有指定最大可接受的消息数量,或者为一个负数,那么就代表可以接受的消息数没有上限。
    Queue的常用属性和方法
    Queue.qsize(): 返回当前队列包含的消息数量;
    Queue.empty(): 如果队列为空, 返回True, 反之False ;
    Queue.full(): 如果队列满了, 返回True,反之False;
    Queue.get([block[, timeout]]): 获取队列中的⼀条消息, 然后将其从列队中移除, block默认值为True;
    (1)如果block使用默认值,且没有设置超时时间,则会堵塞,直到读出消息为止,如果设置了超时时间,则会等待完毕,如果还没收到消息报“Queue.Empty”异常
    (2)如果block值为False,如果没有收到消息,会立即报“Queue.Empty”异常,其中Queue.put_nowait(item): 相当于Queue.put(item, False);

    Queue用于进程通信

    from multiprocessing import Process, Queue
    import os, time, random
    
    
    # 写数据进程执⾏的代码:
    def write(q):
        for value in ['A', 'B', 'C']:
            print('Put %s to queue...' % value)
            q.put(value)
            time.sleep(random.random())
    # 读数据进程执⾏的代码:
    
    def read(q):
        while True:
            if not q.empty():
                value = q.get(True)
                print('Get %s from queue.' % value)
                time.sleep(random.random())
            else:
                break
    
    if __name__ == '__main__':
        # ⽗进程创建Queue, 并传给各个⼦进程:
        q = Queue()
        pw = Process(target=write, args=(q,))
        pr = Process(target=read, args=(q,))
        # 启动⼦进程pw, 写⼊:
        pw.start()
        # 等待pw结束:
        pw.join()
        # 启动⼦进程pr, 读取:
        pr.start()
        pr.join()
        # pr进程⾥是死循环, ⽆法等待其结束, 只能强⾏终⽌:
        print('')
        print('所有数据都写⼊并且读完')
    运行结果
    Put A to queue...
    Put B to queue...
    Put C to queue...
    Get A from queue.
    Get B from queue.
    Get C from queue.
    
    所有数据都写⼊并且读完
    进程池中使用Queue
    如果要在pool中使用进程,就要用到multiprocessing.Manager()中的Queue(),而不能是multiprocessing.Queue(),否则会报异常:RuntimeError: Queue objects should only be shared between processes
    #coding=utf-8
    #修改import中的Queue为Manager
    from multiprocessing import Manager,Pool
    import os,time,random
    
    
    def reader(q):
        print("reader启动(%s),⽗进程为(%s)"%(os.getpid(),os.getppid()))
        for i in range(q.qsize()):
            print("reader从Queue获取到消息: %s"%q.get(True))
    
    def writer(q):
        print("writer启动(%s),⽗进程为(%s)"%(os.getpid(),os.getppid()))
        for i in "dongGe":
            q.put(i)
    
    if __name__=="__main__":
        print("(%s) start"%os.getpid())
    
    q=Manager().Queue() #使⽤Manager中的Queue来初始化
    po=Pool()
    #使⽤阻塞模式创建进程, 这样就不需要在reader中使⽤死循环了, 可以让writer完全执⾏完
    po.apply(writer,(q,))
    po.apply(reader,(q,))
    po.close()
    po.join()
    print("(%s) End"%os.getpid())
    运行结果
    (5740) start
    writer启动(5746),⽗进程为(5740)
    reader启动(5747),⽗进程为(5740)
    reader从Queue获取到消息: d
    reader从Queue获取到消息: o
    reader从Queue获取到消息: n
    reader从Queue获取到消息: g
    reader从Queue获取到消息: G
    reader从Queue获取到消息: e
    (5740) End
  • 相关阅读:
    BZOJ1049 [HAOI2006]数字序列0
    UOJ265 【NOIP2016】愤怒的小鸟
    #include <deque>
    #include <queue>
    #include <vector>
    #include <set>
    #include <map>
    BZOJ1217:[HNOI2003]消防局的设立
    浅谈贪心
    CF1060B:Maximum Sum of Digits
  • 原文地址:https://www.cnblogs.com/hulichao/p/9656696.html
Copyright © 2011-2022 走看看