python多处理回调
我有一个函数列表,可以完成一些工作,比如从url下载html(每个函数都非常不同,所以我无法创建一个函数来接受url和downlaod)。我使用了多处理来加速任务。下面是我的代码python多处理回调,python,python-2.7,multiprocessing,Python,Python 2.7,Multiprocessing,我有一个函数列表,可以完成一些工作,比如从url下载html(每个函数都非常不同,所以我无法创建一个函数来接受url和downlaod)。我使用了多处理来加速任务。下面是我的代码 def runInParallel(list_of_functions): for fn in list_of_functions: proc = [Process(target=fn[1]).start() for fn in list_of_functions] for p in proc:
def runInParallel(list_of_functions):
for fn in list_of_functions:
proc = [Process(target=fn[1]).start() for fn in list_of_functions]
for p in proc:
p.join()
我想要的是如何存储每个函数返回的结果?每个函数都返回一个dict,我需要解析它并将其存储在数据库中,我不想在每个函数中重复这些步骤,所以我想要的是某种回调,可以通过函数返回的结果来传递。
我怎样才能做到这一点
编辑:使用池
但抛出错误。我有以下函数列表:
[('f1', <function f1 at 0x7f34c11c9ed8>), ('f2', <function f2 at 0x7f34c11c9f50>)]
def runInParallel(list_of_functions):
import multiprocessing
pool = multiprocessing.Pool(processes = 3)
x = pool.map(lambda f: f(), list_of_functions)
print x
File "main.py", line 31, in <module>
runInParallel(all_functions)
File "main.py", line 11, in runInParallel
x = pool.map(lambda f: f(), list_of_functions)
File "/usr/lib/python2.7/multiprocessing/pool.py", line 251, in map
return self.map_async(func, iterable, chunksize).get()
File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get
raise self._value
cPickle.PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
[('f1',),('f2',)]
def并行运行(函数列表):
导入多处理
池=多处理。池(进程=3)
x=pool.map(lambda f:f(),函数列表)
打印x
文件“main.py”,第31行,在
并行运行(所有_函数)
文件“main.py”,第11行,并行运行
x=pool.map(lambda f:f(),函数列表)
文件“/usr/lib/python2.7/multiprocessing/pool.py”,第251行,在地图中
返回self.map\u async(func,iterable,chunksize).get()
get中的文件“/usr/lib/python2.7/multiprocessing/pool.py”,第558行
提升自我价值
cPickle.PicklingError:无法pickle:属性查找\内置\函数失败
如上所述:如果您直接使用流程
,您需要设置一个队列,流程将放入其中,这样您就可以从父流程获取
:
from multiprocessing import Process, Queue
from time import sleep
def f1(queue):
sleep(1) # get url, "simulated" by sleep
queue.put(dict(iam="type 1"))
def f2(queue):
sleep(1.5)
queue.put(dict(iam="type 2"))
def f3(queue):
sleep(0.5)
queue.put(dict(iam="type 3"))
def runInParallel(list_of_functions):
queue = Queue()
for fn in list_of_functions:
proc = [Process(target=fn[1], args=(queue,)) for fn in list_of_functions]
for p in proc:
p.start()
res = []
for p in proc:
p.join()
res.append(queue.get())
return res
if __name__ == '__main__':
list_of_functions = [("f1", f1), ("f2", f2), ("f3", f3)]
for d in runInParallel(list_of_functions):
print d
印刷品:
{'iam': 'type 3'}
{'iam': 'type f1'}
{'iam': 'type f2'}
{'url': 'http://url1', 'iam': 'type 1'}
{'url': 'http://url2', 'iam': 'type 2'}
{'url': 'http://url3', 'iam': 'type 3'}
如果您的函数基本上都是相同的(获取URL并以某种方式处理html),那么将您的函数合并成一个具有If
/elif
逻辑的函数,允许您使用map
,您不需要任何队列:
from multiprocessing import Pool
from time import sleep
def f(arg):
url, typ = arg
if typ == 'a':
sleep(1) # instead you would do something with `url` here
return dict(iam="type 1", url=url)
elif typ == 'b':
sleep(1.5)
return dict(iam="type 2", url=url)
elif typ == 'c':
sleep(0.5)
return dict(iam="type 3", url=url)
def runInParallel(work):
p = Pool(3)
return p.map(f, work)
if __name__ == '__main__':
work = [('http://url1', 'a'),
('http://url2', 'b'),
('http://url3', 'c'),
]
for d in runInParallel(work):
print d
印刷品:
{'iam': 'type 3'}
{'iam': 'type f1'}
{'iam': 'type f2'}
{'url': 'http://url1', 'iam': 'type 1'}
{'url': 'http://url2', 'iam': 'type 2'}
{'url': 'http://url3', 'iam': 'type 3'}
这两个脚本在Windows上和在Unix环境下一样工作(在OSX上试用过)可能与See ALLOW和@DavidW重复感谢您的响应,但我如何调整results=[result\u queue.get()for mc in montecarlos]
在我的代码中?@RolandSmithmap(lambda f:f(),函数列表)
应该仍然有效,即使它们都不同,我认为?@RolandSmith类似于映射(lamdba f,args:f(args),zip(函数列表,args元组列表))
?