美文网首页
[python] 多进程通信

[python] 多进程通信

作者: StormZhu | 来源:发表于2018-05-06 21:31 被阅读0次

    引言

    进程间通信与线程间通信有相同的地方,也有不同的地方。threading模块中用于线程同步的机制在进程中是不能够使用的,queue模块中的Queue类也是不能用的。举个例子:

    from multiprocessing import Process
    import time
    from queue import Queue
    
    def producer(queue):
        queue.put('a')
        time.sleep(2)
    
    def consumer(queue):
        time.sleep(2)
        data = queue.get()
        print(data)
    
    if __name__ == "__main__":
        queue = Queue(10)
        my_producer = Process(target=producer, args=(queue,))
        my_consumer = Process(target=consumer, args=(queue,))
        my_producer.start()
        my_consumer.start()
        my_producer.join()
        my_consumer.join()
    # 执行结果
    # TypeError: can't pickle _thread.lock objects
    

    可以看出,运行是报错了,虽然不能使用queue模块,但是multiprocessing模块提供了其他的方法。

    进程通信

    Queue

    multiprocessing模块提供了适合进程通信的Queue类,用法和queue模块中的Queue一模一样,只是导入的包不一样。

    from multiprocessing import Process, Queue
    import time
    
    
    def producer(queue):
        queue.put('a')
        time.sleep(2)
    
    def consumer(queue):
        time.sleep(2)
        data = queue.get()
        print(data)
    
    if __name__ == "__main__":
        queue = Queue(10)
        my_producer = Process(target=producer, args=(queue,))
        my_consumer = Process(target=consumer, args=(queue,))
        my_producer.start()
        my_consumer.start()
        my_producer.join()
        my_consumer.join()
    

    值得注意的是:对于multiprocessing模块中提供的进程池Pool类,Queue是不支持的!

    Manager

    multiprocessing模块中的Manager类也可用于进程同步且,更为强大,将其实例化之后,其中也存在Queue,用法相同,并且可以用于multiprocessing模块中提供的进程池Pool类。

    除此之外,Manager里面提供了listdictValueSemaphoreLockCondition等用于进程同步的机制。举个dict的例子:

    from multiprocessing import Process
    from multiprocessing import Manager
    
    def add_data(p_dict, key, value):
        p_dict[key] = value
    
    if __name__ == "__main__":
        progress_dict = Manager().dict()
        first_progress = Process(target=add_data, args=(progress_dict,'key1','10'))
        second_progress = Process(target=add_data, args=(progress_dict,'key2','11'))
        first_progress.start()
        second_progress.start()
        first_progress.join()
        second_progress.join()
    
        print(progress_dict)
    # 执行结果
    # {'key1': '10', 'key2': '11'}
    

    可以看到,两个进程同时操作同一个变量,确实都成功了。如果讲Manager().dict()换成普通的dict(),结果打印出来一定是空字典。

    Pipe

    pipe是简化办的Queue,只能用于两个进程之间通信,不适用于多个,优点是速度相对于Queue更快。

    from multiprocessing import Process, Pipe
    import time
    
    def producer(pipe):
        pipe.send('send to you')
        time.sleep(2)
        data = pipe.recv()
        print('In producer recv:', data)
    
    
    def consumer(pipe):
        time.sleep(2)
        data = pipe.recv()
        print('In consumer recv:',data)
        pipe.send('I recv')
    
    if __name__ == "__main__":
        receive_pipe, send_pipe = Pipe()
        my_producer = Process(target=producer, args=(receive_pipe,))
        my_consumer = Process(target=consumer, args=(send_pipe,))
        my_producer.start()
        my_consumer.start()
        my_producer.join()
        my_consumer.join()
    # 执行结果
    # In consumer recv: send to you
    # In producer recv: I recv
    

    Pipe管道构建的时候返回两个对象,这两个对象之间可以通过sendrecv方法传递数据。

    总结

    • 进程通信有Queue、Manager和Pipe三种方法。

    参考

    Python3高级编程和异步IO并发编程

    相关文章

      网友评论

          本文标题:[python] 多进程通信

          本文链接:https://www.haomeiwen.com/subject/ahzrrftx.html