生产者消费者模型书写,使用多进程实现服务端并发-练习
一. 手动书写生产者消费者代码
from multiprocessing import Process
from multiprocessing import JoinableQueue
import time
import random
def producer(name, food, q):
for i in range(4):
data = f'{food}{i}'
time.sleep(random.uniform(1, 2))
print(f'生产者{name}生产了{data}')
q.put(data)
def customer(name, q):
while True:
data = q.get()
time.sleep(random.choice([1, 2]))
print(f'消费者{name}购买了{data}')
q.task_done() # 没执行一次队列数据计数器-1
if __name__ == '__main__':
q = JoinableQueue()
p1 = Process(target=producer, args=('tank', '包子', q))
p2 = Process(target=producer, args=('egon', '泔水', q))
c1 = Process(target=customer, args=('TANK', q))
c2 = Process(target=customer, args=('EGON', q))
# 设置消费者为守护进程. 目的是当所有生产者生产数据完毕, 且队列中数据被消费者取完毕. 结束主进程, 进而使消费者这个守护进程结束
c1.daemon = True
c2.daemon = True
p1.start()
p2.start()
c1.start()
c2.start()
# 上面已经向操作系统发起了开启消费者和生产者的请求. 让主进程等所有生产者执行完毕, 防止主进程直接结束, 进而让所有消费者子进程也结束.
p1.join()
p2.join()
# 当计数器计算到队列中的数据为空了, 那么也就代表所有消费者把所有生产者的数据取完了, 消费者没有存在的必要了, 这时可以执行下一行代码了, 也表示主进程结束了, 同时消费者守护进程们也要结束了.
q.join()
二. 思考: 如何实现TCP服务端并发的效果
思路: 服务端起多个进程, 每个进程都单独与客户端进行通信循环.
TCP服务端
from socket import *
from multiprocessing import Process
import os
def communication(conn):
print(f'客户端{os.getpid()}建立连接!')
while True:
try:
data_bytes = conn.recv(1024)
if not data_bytes:
break
conn.send(data_bytes.upper())
except ConnectionResetError:
break
conn.close()
if __name__ == '__main__':
server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
conn, client_address = server.accept()
p = Process(target=communication, args=(conn, ))
p.start()
server.close()
TCP客户端
from socket import *
client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8080))
while True:
msg = input(">>: ").strip()
if not msg:
continue
client.send(msg.encode('utf-8'))
data_bytes = client.recv(1024)
print(data_bytes)
client.close()