Python 使多线程池在类内工作
我试图让这段代码在一个类下工作,但我怎么能做到呢 实际工作代码:Python 使多线程池在类内工作,python,python-2.7,Python,Python 2.7,我试图让这段代码在一个类下工作,但我怎么能做到呢 实际工作代码: import multiprocessing from datetime import datetime def get_list(): the_list = ["a", "b", "c"] return the_list def print_list(names): for result in names: print "%s\t%s" % (multiprocessing.c
import multiprocessing
from datetime import datetime
def get_list():
the_list = ["a", "b", "c"]
return the_list
def print_list(names):
for result in names:
print "%s\t%s" % (multiprocessing.current_process().name,result)
def start_process():
print 'Starting', multiprocessing.current_process().name
def mp_handler():
data = get_list()
print "Pool size :", len(data)
pool_size = 1
p = multiprocessing.Pool(processes=pool_size, initializer=start_process)
p.map(print_list, data)
p.close()
p.join()
if __name__ == '__main__':
start_time = datetime.now()
mp_handler()
print "runtime : %s" % (datetime.now() - start_time)
输出:
Pool size : 3
Starting PoolWorker-1
PoolWorker-1 a
PoolWorker-1 b
PoolWorker-1 c
runtime : 0:00:00.458000
Process finished with exit code 0
我试图做的,但我得到了错误:
import multiprocessing
from datetime import datetime
class m_test():
def __init__(self):
this_mod='some test'
def get_list(self):
the_list = ["a", "b", "c"]
return the_list
def print_list(self, names):
for result in names:
print "%s\t%s" % (multiprocessing.current_process().name,result)
def start_process(self):
print 'Starting', multiprocessing.current_process().name
def mp_handler(self):
data = self.get_list()
print "Pool size :", len(data)
pool_size = 1
p = multiprocessing.Pool(processes=pool_size, initializer=self.start_process)
p.map(self.print_list, data)
p.close()
p.join()
if __name__ == '__main__':
start_time = datetime.now()
start = m_test()
start.mp_handler()
print "runtime : %s" % (datetime.now() - start_time)
输出:
Pool size : 3
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 808, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 761, in run
self.__target(*self.__args, **self.__kwargs)
File "C:\Python27\lib\multiprocessing\pool.py", line 342, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed
池大小:3
线程2中的异常:
回溯(最近一次呼叫最后一次):
文件“C:\Python27\lib\threading.py”,第808行,在引导程序内部
self.run()
文件“C:\Python27\lib\threading.py”,第761行,正在运行
自我目标(*自我参数,**自我参数)
文件“C:\Python27\lib\multiprocessing\pool.py”,第342行,在任务处理中
放置(任务)
PicklingError:无法pickle:属性查找\内置\实例方法失败
提前感谢。如错误消息所示,问题在于不能对实例方法进行pickle处理,
多处理
模块需要能够这样做才能对类的实例进行操作。要将参数传递给多处理进程
,必须能够使用pickle对参数进行序列化
一个简单的解决方法是定义与需要调用的实例的每个方法相对应的全局函数。这些“helper”函数必须向它们传递一个实例,这样它们才能将调用转发到适当的对象(以及可能检索这样做可能需要的任何参数)。我的意思是:
此版本中的重要修订是为了解决您在评论中提出的问题,即为什么以前的版本没有从池中一次运行多个进程,该修订是为了在创建多处理.Pool
时添加maxstasksparchild
关键字参数。设置此选项将使工作进程/子进程在最多完成指定的任务数后(重新)启动,因为默认情况下,即使Pool
创建一个processs=Pool\u size
进程数,map()
将尝试为iterable中的每个项调用同一个函数
import multiprocessing
from datetime import datetime
class M_Test():
def __init__(self):
this_mod='some test'
def get_list(self):
the_list = ["a", "b", "c"]
return the_list
def print_list(self, names):
print("%s\tprint_list(%r) called" % ( # added statement
multiprocessing.current_process().name,names))
for result in names:
print("%s\t processing %r" % (multiprocessing.current_process().name,result))
def start_process(self):
print('Starting %s' % multiprocessing.current_process().name)
def mp_handler(self):
data = self.get_list()
pool_size = 1
print("Pool size : %s" % pool_size)
p = multiprocessing.Pool(processes=pool_size,
initializer=initializer, initargs=(self,),
maxtasksperchild=1) # additional keyword arg
p.map(print_list, (self,)*len(data))
p.close() # don't create any more tasks
p.join() # finish all currently running ones
# "helper" functions
def initializer(inst):
inst.start_process()
def print_list(inst):
inst.print_list(inst.get_list())
if __name__ == '__main__':
start_time = datetime.now()
start = M_Test()
start.mp_handler()
print("runtime : %s" % (datetime.now() - start_time))
输出:
Pool size : 3
Starting PoolWorker-1
PoolWorker-1 a
PoolWorker-1 b
PoolWorker-1 c
runtime : 0:00:00.458000
Process finished with exit code 0
池大小:1
启动PoolWorker-1
调用PoolWorker-1打印列表(['a','b','c'])
PoolWorker-1正在处理“a”
PoolWorker-1正在处理“b”
PoolWorker-1处理“c”
启动PoolWorker-2
调用PoolWorker-2打印列表(['a','b','c'])
PoolWorker-2处理“a”
PoolWorker-2正在处理“b”
PoolWorker-2处理“c”
初级工人-3
调用PoolWorker-3打印列表(['a','b','c'])
PoolWorker-3处理“a”
PoolWorker-3处理“b”
PoolWorker-3处理“c”
运行时间:0:00:01.219000
输出与非基于类的版本不太一样,但我相信这可能是您真正希望看到的结果。我还对print语句做了一些修改,以提供关于正在发生的事情的更清晰的信息。print“Pool size:,len(data)”只是为了输出更多的信息:)好吧,类似于print“Pool size:,Pool_size
的东西可以完成同样的事情,并提供准确且潜在有用的信息。至于将self
多次传递到p.map()
:只有一个类M_测试
对象的实例可以通过它。我有点困惑,multiprocessing.Pool.map()
函数没有初始化多个Pool
进程——但在非基于类的版本中也没有(设置它的Pool\u size=3
以查看)。如果我发现我的理解有什么问题,我会进一步研究这个问题并更新我的答案。我也在研究这个问题,但非常感谢你在这个问题上的帮助=)你没有接受我的答案有什么原因吗?在我看来,它解决了你的核心问题。