Python自定义进程池实例分析【生产者、消费者模型问题】
作者:RQSLT 发布时间:2023-05-20 12:20:02
标签:Python,自定义,进程池
本文实例分析了Python自定义进程池。分享给大家供大家参考,具体如下:
代码说明一切:
#encoding=utf-8
#author: walker
#date: 2014-05-21
#function: 自定义进程池遍历目录下文件
from multiprocessing import Process, Queue, Lock
import time, os
#消费者
class Consumer(Process):
def __init__(self, queue, ioLock):
super(Consumer, self).__init__()
self.queue = queue
self.ioLock = ioLock
def run(self):
while True:
task = self.queue.get() #队列中无任务时,会阻塞进程
if isinstance(task, str) and task == 'quit':
break;
time.sleep(1) #假定任务处理需要1秒钟
self.ioLock.acquire()
print( str(os.getpid()) + ' ' + task)
self.ioLock.release()
self.ioLock.acquire()
print 'Bye-bye'
self.ioLock.release()
#生产者
def Producer():
queue = Queue() #这个队列是进程/线程安全的
ioLock = Lock()
subNum = 4 #子进程数量
workers = build_worker_pool(queue, ioLock, subNum)
start_time = time.time()
for parent, dirnames, filenames in os.walk(r'D:\test'):
for filename in filenames:
queue.put(filename)
ioLock.acquire()
print('qsize:' + str(queue.qsize()))
ioLock.release()
while queue.qsize() > subNum * 10: #控制队列中任务数量
time.sleep(1)
for worker in workers:
queue.put('quit')
for worker in workers:
worker.join()
ioLock.acquire()
print('Done! Time taken: {}'.format(time.time() - start_time))
ioLock.release()
#创建进程池
def build_worker_pool(queue, ioLock, size):
workers = []
for _ in range(size):
worker = Consumer(queue, ioLock)
worker.start()
workers.append(worker)
return workers
if __name__ == '__main__':
Producer()
ps:
self.ioLock.acquire()
...
self.ioLock.release()
可用:
with self.ioLock:
...
替代。
再来一个好玩的例子:
#encoding=utf-8
#author: walker
#date: 2016-01-06
#function: 一个多进程的好玩例子
import os, sys, time
from multiprocessing import Pool
cur_dir_fullpath = os.path.dirname(os.path.abspath(__file__))
g_List = ['a']
#修改全局变量g_List
def ModifyDict_1():
global g_List
g_List.append('b')
#修改全局变量g_List
def ModifyDict_2():
global g_List
g_List.append('c')
#处理一个
def ProcOne(num):
print('ProcOne ' + str(num) + ', g_List:' + repr(g_List))
#处理所有
def ProcAll():
pool = Pool(processes = 4)
for i in range(1, 20):
#ProcOne(i)
#pool.apply(ProcOne, (i,))
pool.apply_async(ProcOne, (i,))
pool.close()
pool.join()
ModifyDict_1() #修改全局变量g_List
if __name__ == '__main__':
ModifyDict_2() #修改全局变量g_List
print('In main g_List :' + repr(g_List))
ProcAll()
Windows7 下运行的结果:
λ python3 demo.py
In main g_List :['a', 'b', 'c']
ProcOne 1, g_List:['a', 'b']
ProcOne 2, g_List:['a', 'b']
ProcOne 3, g_List:['a', 'b']
ProcOne 4, g_List:['a', 'b']
ProcOne 5, g_List:['a', 'b']
ProcOne 6, g_List:['a', 'b']
ProcOne 7, g_List:['a', 'b']
ProcOne 8, g_List:['a', 'b']
ProcOne 9, g_List:['a', 'b']
ProcOne 10, g_List:['a', 'b']
ProcOne 11, g_List:['a', 'b']
ProcOne 12, g_List:['a', 'b']
ProcOne 13, g_List:['a', 'b']
ProcOne 14, g_List:['a', 'b']
ProcOne 15, g_List:['a', 'b']
ProcOne 16, g_List:['a', 'b']
ProcOne 17, g_List:['a', 'b']
ProcOne 18, g_List:['a', 'b']
ProcOne 19, g_List:['a', 'b']
Ubuntu 14.04下运行的结果:
In main g_List :['a', 'b', 'c']
ProcOne 1, g_List:['a', 'b', 'c']
ProcOne 2, g_List:['a', 'b', 'c']
ProcOne 3, g_List:['a', 'b', 'c']
ProcOne 5, g_List:['a', 'b', 'c']
ProcOne 4, g_List:['a', 'b', 'c']
ProcOne 8, g_List:['a', 'b', 'c']
ProcOne 9, g_List:['a', 'b', 'c']
ProcOne 7, g_List:['a', 'b', 'c']
ProcOne 11, g_List:['a', 'b', 'c']
ProcOne 6, g_List:['a', 'b', 'c']
ProcOne 12, g_List:['a', 'b', 'c']
ProcOne 13, g_List:['a', 'b', 'c']
ProcOne 10, g_List:['a', 'b', 'c']
ProcOne 14, g_List:['a', 'b', 'c']
ProcOne 15, g_List:['a', 'b', 'c']
ProcOne 16, g_List:['a', 'b', 'c']
ProcOne 17, g_List:['a', 'b', 'c']
ProcOne 18, g_List:['a', 'b', 'c']
ProcOne 19, g_List:['a', 'b', 'c']
可以看见Windows7下第二次修改没有成功,而Ubuntu下修改成功了。据uliweb作者limodou讲,原因是Windows下是充重启实现的子进程;Linux下是fork实现的。
希望本文所述对大家Python程序设计有所帮助。


猜你喜欢
- 它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, Adi
- 前言首先明确一点这个错误只会发生在delete语句或者update语句,拿update来举例 : update A表 set A列 = (s
- 数据API数据集方法不会修改数据集,而是创建新数据集。可通过调用 map() 方法将转换应用于每个元素:dataset = dataset.
- 引言Supabase是一个自称的 "开源Firebase替代品"。我对与Supbase合作已经有一段时间了,我想我将尝试
- Python 下的单例模式要点:1.某个类只能有一个实例;2.它必须自行创建这个实例;3.它必须自行向整个系统提供这个实例方法:重写new函
- 我们知道Vscode是一款强大的编辑器,我们可以通过商城里面的插件扩展来写C/C++/python/java等。同样Vscode支持SQL语
- 1 、据说python3就没有这个问题了2 、u'字符串' 代表是unicode格式的数据,路径最好写成这个格式,别直接跟字
- 1.0 为什么要做这个博客站?在工作学习中,经常要搜索查找各种各样的资料,每次找到相关资料后都会顺手添加到浏览器书签中,时间一长,书签也就满
- 每个微信小程序都可以有自己的本地缓存,可以通过 wx.setStorage(wx.setStorageSync)、wx.getStorage
- 背景 在平常的开发中,经常碰到这种更新数据的场景:先判断某一数据在库表中是否存在,存在则update,不存在则insert。 如果使用Hi
- 当业务A页面有验证码,且业务B页面也需要验证码。这个时候,如果A和B共用一个验证码,则会出现这种情况:A页面出现验证码,这个时候打开B页面验
- CREATETABLE`users`(`id`int(10)NOTNULLAUTO_INCREMENT,`name`char(50)NOTN
- 在输出代码行中,加入“index=False”如下:m_pred_survived.to_csv("clasified.csv&q
- 前言最近学完Python,写了几个爬虫练练手,网上的教程有很多,但是有的已经不能爬了,主要是网站经常改,可是爬虫还是有通用的思路的,即下载数
- 本文实例讲述了CodeIgniter分页类pagination使用方法。分享给大家供大家参考,具体如下:controller控制器(appl
- 在asp.net 2.0中,很多情况下,使用gridview控件的话,甚至只需要拖拉控件,设置属性就可
- 一、迭代器(Iterator)1.1 可迭代对象(Iterable)可迭代对象,可以简单理解为可遍历对象,即能够使用 for 循环遍历的对象
- <%on error resume nextdim conn,sql,rsset conn=Server.CreateObject(&
- 本文实例讲述了pymongo为mongodb数据库添加索引的方法。分享给大家供大家参考。具体实现方法如下:from pymongo impo
- 前言调用EXPLAIN可以获取关于查询执行计划的信息,以及如何解释输出。EXPLAIN命令是查看查询优化器如何决定执行查询的主要方法,但该动