博客
关于我
Python_生产者消费者模型、管道、数据共享、进程池
阅读量:800 次
发布时间:2023-03-09

本文共 2659 字,大约阅读时间需要 8 分钟。

生产者消费者模型、管道与数据共享的分析

生产者消费者模型

生产者消费者模型是处理数据生产与消费的经典模式,适用于分布式系统中的数据处理。生产者负责生产数据,消费者负责消费数据。这种模型通过队列进行通信,保证了数据的有序性和安全性。以下是使用Python的multiprocessing模块实现的生产者消费者模型示例:

import timeimport randomfrom multiprocessing import Process, Queuedef consumer(q):    while True:        obj = q.get()        print(f'消费了一个数据{obj}')        time.sleep(random.randint(1, 3))if __name__ == "__main__":    q = Queue()    Process(target=consumer, args=(q,)).start()    for i in range(10):        time.sleep(random.randint(1, 5))        q.put(f'food{i}')        print(f'生产了一个数据food{i}')

结果示例

运行上述代码会观察到生产者和消费者交替工作的现象,随着时间的推移,队列中的数据会被逐一消费完毕。

阻塞队列

在上述模型中,q.get()是阻塞操作,直到队列中有数据被放入为止。这保证了生产者和消费者能够高效地进行数据交换。

管道通信

管道(Pipe)是多进程间通信的基础设施,通过一个双向通道实现数据的传递。以下是一个简单的管道通信示例:

from multiprocessing import Pipe, Processdef consumer(lp, rp):    lp.close()    while True:        try:            print(rp.recv())        except EOFError:            breakif __name__ == "__main__":    lp, rp = Pipe()    Process(target=consumer, args=(lp, rp)).start()    Process(target=consumer, args=(lp, rp)).start()    Process(target=consumer, args=(lp, rp)).start()    Process(target=consumer, args=(lp, rp)).start()    Process(target=consumer, args=(lp, rp)).start()    rp.close()    for i in range(500):        lp.send(f'food{i}')    lp.close()

结果示例

运行上述代码会发现,主进程将500个“food”对象发送到管道中,随后所有进程都会退出,完成任务。

数据共享

在多进程环境下,共享数据需要谨慎处理,否则可能导致数据竞争和不一致性。普通模式下,直接使用共享数据可能会出现问题:

from multiprocessing import Manager, Process, Lockdef work(d, lock):    with lock:        d['count'] -= 1if __name__ == "__main__":    lock = Lock()    m = Manager()    dic = m.dict({'count': 100})    p_l = []    for i in range(100):        p = Process(target=work, args=(dic, lock))        p_l.append(p)        p.start()    for p in p_l:        p.join()    print(dic)

结果示例

运行上述代码后,dic中的count会减少到0,表明所有进程都完成了工作。

上下文管理模式

为了避免数据竞争,可以使用上下文管理器:

from multiprocessing import Manager, Process, Lockdef work(d, lock):    with lock:        d['count'] -= 1if __name__ == "__main__":    with Manager() as m:        dic = m.dict({'count': 100})        p_l = []        for i in range(100):            p = Process(target=work, args=(dic, lock))            p_l.append(p)            p.start()        for p in p_l:            p.join()        print(dic)

结果示例

与普通模式结果一致,dic中的count减少到0。

进程池的使用

进程池提供了更高效的任务调度方式,适用于需要多进程执行的任务。以下是一个使用进程池的示例:

import osimport timedef wahaha(num):    print(f'子{os.getpid()}')    return num ** numdef call(argv):    print(f'主{os.getpid()}')    print(argv)if __name__ == "__main__":    print('主', os.getpid())    p = Pool(5)    p.apply_async(func=wahaha, args=(50,), callback=call)    p.close()    p.join()

结果示例

运行上述代码会看到主进程和子进程交替输出信息,最终所有任务完成后,进程池关闭。

转载地址:http://djlfk.baihongyu.com/

你可能感兴趣的文章
python初步学习-python数据类型-集合(set)
查看>>
python列表生成字典_Python中将字典转换为列表的方法
查看>>
python列表对应元素合并为列表及判断一个列表是几维
查看>>
python+flask计算机毕业设计高校校园线上跳蚤市场的系统设计(程序+开题+论文)
查看>>
python+flask计算机毕业设计高校疫情防控管理平台(程序+开题+论文)
查看>>
Python+Jenkins+Allure Report接口自动化测试持续集成
查看>>
python+locust电商全流程性能测试
查看>>
Python函数运行的可执行文件的终端输出如何以一般方式静音?
查看>>
Python+Pytest+Allure+Git+Jenkins接口自动化框架
查看>>
python+pytest接口自动化 —— 参数关联
查看>>
python+pytest接口自动化 —— 参数关联
查看>>
python+pytest接口自动化 —— 自动化用例编写思路 (使用pytest编写一个测试脚本)
查看>>
Python+pytest接口自动化之cookie绕过登录(保持登录状态)
查看>>
python+pytest接口自动化:接口测试
查看>>
Python+requests+unittest执行接口自动化测试详情
查看>>
Python+requests+unittest执行接口自动化测试详情
查看>>
python+requests+unittest执行自动化接口测试!
查看>>
Python+Requests编码识别Bug
查看>>
python函数编写_[零基础学python]传说中的函数编写条规
查看>>
Python+selenium —— UI自动化之鼠标操作
查看>>