1、使用进程
1.1 使用multiprocessing.Process() + 列表 + multiprocessing.Manager().Queue()
实现多生产者多消费者
import multiprocessing
from multiprocessing import Manager, Queue, JoinableQueue
import time
def producer(que, name):
for i in range(2):
if not que.full():
print(name + "生产了数据:%d" % i)
que.put(i)
time.sleep(0.5)
def consumer(que, name):
while True:
if not que.empty():
data = que.get()
que.task_done()
print(name + "消费了数据:%d" % data)
else:
time.sleep(0.6)
if que.empty():
break
time.sleep(0.5)
if __name__ == '__main__':
# que = Queue()
# que = JoinableQueue()
que = Manager().Queue()
consumers = producers = []
for i in range(3):
consumers.append(multiprocessing.Process(target=producer, args=(que, "producer" + str(i))))
consumers[-1].start()
for i in range(2):
producers.append(multiprocessing.Process(target=consumer, args=(que, "consumer" + str(i))))
producers[-1].start()
for c in consumers:
c.join()
for p in producers:
p.join()
"""
运行结果:
producer0生产了数据:0
producer1生产了数据:0
producer2生产了数据:0
consumer0消费了数据:0
consumer1消费了数据:0
producer0生产了数据:1
producer1生产了数据:1
producer2生产了数据:1
consumer0消费了数据:0
consumer1消费了数据:1
consumer0消费了数据:1
consumer1消费了数据:1
Process finished with exit code 0
"""
"""
注意:queue.Queue(),multiprocessing.Queue(),multiprocessing.JoinableQueue(),multiprocessing.Manager().Queue()四个队列的区别。
"""
1.2、使用ProcessPoolExecutor() + multiprocessing.Manager().Queue()
实现多生产者多消费者
from concurrent.futures import ProcessPoolExecutor
import time
from multiprocessing import Manager
def producer(que, name):
for i in range(2):
if not que.full():
print(name + "生产了数据:%d" % i)
que.put(i)
time.sleep(0.5)
def consumer(que, name):
while True:
if not que.empty():
data = que.get()
que.task_done()
print(name + "消费了数据:%d" % data)
else:
time.sleep(0.6)
if que.empty():
break
time.sleep(0.5)
if __name__ == '__main__':
que = Manager().Queue()
pool = ProcessPoolExecutor(max_workers=5)
for i in range(3):
pool.submit(producer, que, "producer" + str(i))
for i in range(2):
pool.submit(consumer, que, "consumer" + str(i))
pool.shutdown(wait=True)
print('主进程完成')
"""
运行结果:
producer0生产了数据:0
producer1生产了数据:0
producer2生产了数据:0
consumer0消费了数据:0
consumer1消费了数据:0
producer0生产了数据:1
producer1生产了数据:1
producer2生产了数据:1
consumer0消费了数据:0
consumer1消费了数据:1
consumer0消费了数据:1
consumer1消费了数据:1
主进程完成
Process finished with exit code 0
"""
1.3 使用multiprocessing.Pool() + multiprocessing.Manager().Queue()
实现多生产者多消费者
import multiprocessing
from multiprocessing import Manager
import time
def producer(que, name):
for i in range(2):
if not que.full():
print(name + "生产了数据:%d" % i)
que.put(i)
time.sleep(0.5)
def consumer(que, name):
while True:
if not que.empty():
data = que.get()
que.task_done()
print(name + "消费了数据:%d" % data)
else:
time.sleep(0.6)
if que.empty():
break
time.sleep(0.5)
if __name__ == '__main__':
que = Manager().Queue()
pool = multiprocessing.Pool(processes=5)
for i in range(3):
pool.apply_async(producer, (que, "producer" + str(i)))
for i in range(2):
pool.apply_async(consumer, (que, "consumer" + str(i)))
pool.close()
pool.join()
print('主进程完成')
"""
运行结果:
producer0生产了数据:0
producer1生产了数据:0
producer2生产了数据:0
consumer0消费了数据:0
consumer1消费了数据:0
producer0生产了数据:1
producer1生产了数据:1
producer2生产了数据:1
consumer0消费了数据:0
consumer1消费了数据:1
consumer0消费了数据:1
consumer1消费了数据:1
主进程完成
Process finished with exit code 0
"""
2、使用线程
2.1、使用threading.Thread() + [ ] + queue.Queue()
实现多生产者多消费者
import threading
import queue
import time
def producer(que, name):
for i in range(2):
if not que.full():
print(name + "生产了数据:%d" % i)
que.put(i)
time.sleep(0.5)
def consumer(que, name):
while True:
if not que.empty():
data = que.get()
que.task_done()
print(name + "消费了数据:%d" % data)
else:
time.sleep(0.6)
if que.empty():
break
time.sleep(0.5)
if __name__ == '__main__':
que = queue.Queue()
consumers = producers = []
for i in range(3):
consumers.append(threading.Thread(target=producer, args=(que, "consumer" + str(i))))
consumers[-1].start()
for i in range(2):
producers.append(threading.Thread(target=consumer, args=(que, "producer" + str(i))))
producers[-1].start()
for c in consumers:
c.join()
for p in producers:
p.join()
"""
运行结果:
consumer0生产了数据:0
consumer1生产了数据:0
consumer2生产了数据:0
producer0消费了数据:0
producer1消费了数据:0
consumer1生产了数据:1
producer0消费了数据:0
consumer2生产了数据:1
producer1消费了数据:1
consumer0生产了数据:1
producer1消费了数据:1
producer0消费了数据:1
Process finished with exit code 0
"""
2.2 使用ThreadPoolExecutor() + queue.Queue()
实现多生产者多消费者
from concurrent.futures import ThreadPoolExecutor
import queue
import time
def producer(que, name):
for i in range(2):
if not que.full():
print(name + "生产了数据:%d" % i)
que.put(i)
time.sleep(0.5)
def consumer(que, name):
while True:
if not que.empty():
data = que.get()
que.task_done()
print(name + "消费了数据:%d" % data)
else:
time.sleep(0.6)
if que.empty():
break
time.sleep(0.5)
if __name__ == '__main__':
que = queue.Queue()
pool = ThreadPoolExecutor(max_workers=5)
for i in range(3):
pool.submit(producer, que, "producer" + str(i))
for i in range(2):
pool.submit(consumer, que, "consumer" + str(i))
pool.shutdown(wait=True)
print('主线程完成')
"""
运行结果:
producer0生产了数据:0
producer1生产了数据:0
producer2生产了数据:0
consumer0消费了数据:0
consumer1消费了数据:0
producer0生产了数据:1
consumer0消费了数据:0
producer2生产了数据:1
producer1生产了数据:1
consumer1消费了数据:1
consumer1消费了数据:1
consumer0消费了数据:1
主线程完成
Process finished with exit code 0
"""
3、使用生成器
生成器只能有一个生产者一个消费者。
def producer(c):
c.send(None)
for data in range(5):
print("生产者生成发送了数据%d" % data)
c.send(data)
c.close()
def consumer():
response = None
while True:
data = yield response
print("消费者接受消费了数据%d" % data)
response = 200
if __name__ == '__main__':
c = consumer()
producer(c)
"""
运行结果:
生产者生成发送了数据0
消费者接受消费了数据0
生产者生成发送了数据1
消费者接受消费了数据1
生产者生成发送了数据2
消费者接受消费了数据2
生产者生成发送了数据3
消费者接受消费了数据3
生产者生成发送了数据4
消费者接受消费了数据4
Process finished with exit code 0
"""
4. 使用multiprocessing.Pipe + multiprocessing.Process/threading.Thread
multiprocessing.Pipe + multiprocessing.Process/threading.Thread只能有一个生产者一个消费者。
from multiprocessing import Pipe, Process
import time
from threading import Thread
def producer(pipe):
for i in range(5):
pipe.send(i)
time.sleep(0.5)
print("send {0} to pipe".format(i))
def consumer(pipe):
n = 5
while n > 0:
result = pipe.recv()
time.sleep(0.5)
print("recv {0} from pipe".format(result))
n -= 1
if __name__ == '__main__':
pipe = Pipe(duplex=False)
print(type(pipe))
# producer_ = Process(target=producer, args=(pipe[1],))
# consumer_ = Process(target=consumer, args=(pipe[0],))
producer_ = Thread(target=producer, args=(pipe[1],))
consumer_ = Thread(target=consumer, args=(pipe[0],))
producer_.start()
consumer_.start()
producer_.join()
consumer_.join()
pipe[0].close()
pipe[1].close()
"""
运行结果:
<class 'tuple'>
send 0 to pipe
recv 0 from pipe
send 1 to pipe
recv 1 from pipe
recv 2 from pipe
send 2 to pipe
send 3 to pipe
recv 3 from pipe
recv 4 from pipe
send 4 to pipe
Process finished with exit code 0
"""
"""
当Pipe的参数duplex=True时,此时Pipe实现全双工通信。
"""
5.使用 asyncio.Queue + asyncio
import asyncio
from asyncio import Queue
async def producer(que, name):
for i in range(2):
if not que.full():
print(name + "生产了数据:%d" % i)
await que.put(i)
await asyncio.sleep(0.5)
async def consumer(que, name):
while True:
if not que.empty():
data = await que.get()
que.task_done()
print(name + "消费了数据:%d" % data)
else:
await asyncio.sleep(5)
if que.empty():
break
await asyncio.sleep(0.5)
if __name__ == '__main__':
que = Queue()
loop = asyncio.get_event_loop()
tasks_producer = [asyncio.ensure_future(producer(que, "producer" + str(i))) for i in range(3)]
tasks_consumer = [asyncio.ensure_future(consumer(que, "consumer" + str(i))) for i in range(2)]
tasks = tasks_producer + tasks_consumer
results = loop.run_until_complete(asyncio.wait(tasks))
loop.close()
"""
运行结果:
producer0生产了数据:0
producer1生产了数据:0
producer2生产了数据:0
consumer0消费了数据:0
consumer1消费了数据:0
producer0生产了数据:1
producer2生产了数据:1
consumer1消费了数据:0
producer1生产了数据:1
consumer0消费了数据:1
consumer1消费了数据:1
consumer0消费了数据:1
Process finished with exit code 0
"""