回顾线程间通信(Python多线程编程之线程间通信),线程间通信用共享变量和queue.Queue。但这两者都不能用于进程间通信。不同进程之间,变量就算同名也是位于不同的内存地址上,也是不同的变量。queue.Queue 也不能用于进程间通信,将不同进程的变量put进queue.Queue对象中,会抛弃常。下面示例代码:
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()
# 运行结果,抛异常退出
1. from multiprocessing import Queue ,multiprocessing 中的 Queue, 不能用于 pool 进程池。
import time
from multiprocessing import Process,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.Queue()
queue = Queue()
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()
"""
运行结果:
a
Process finished with exit code 0
"""
# 使用 multiprocessing.Queue 可以正常实现进程间通信,正常打印出 “a”
2. from multiprocessing import Manager(实例化后调用Queue()可以用于多进程的进程池)
import time
from multiprocessing import Process,Queue,Pool,Manager
def producer(queue):
queue.put("a")
time.sleep(2)
def consumer(queue):
time.sleep(2)
data = queue.get()
print(data)
if __name__ == "__main__":
#pool中的进程间通信需要先实例化Manager,再调用Queue()
queue = Manager().Queue()
pool = Pool()
pool.apply_async(producer,args=(queue,))
pool.apply_async(consumer, args=(queue,))
pool.close()
pool.join()
"""
a
Process finished with exit code 0
"""
3. 管道 Pipe (两进程间的通信优先考虑), pipe的性能高于queue, 因为 queue要加了很多锁。
import time
from multiprocessing import Pool, Pipe
def producer(pipe):
pipe.send("a")
time.sleep(3)
print(pipe.recv())
def consumer(pipe):
time.sleep(2)
data = pipe.recv()
pipe.send("b")
print(data)
if __name__ == "__main__":
# Pipe实现两进程间通信
s_pipe, r_pipe = Pipe()
pool = Pool()
pool.apply_async(producer, args=(s_pipe,))
pool.apply_async(consumer, args=(r_pipe,))
pool.close()
pool.join()
"""
运行结果:
a
b
Process finished with exit code 0
"""