生产者消费者模型书写,使用多进程实现服务端并发-练习

一. 手动书写生产者消费者代码

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()
posted @ 2020-04-23 23:06  给你加马桶唱疏通  阅读(171)  评论(0编辑  收藏  举报