您好我尝试使用多处理来加速我的代码。但是,apply_async并不适合我。我试着做一个简单的例子:
from multiprocessing.pool import Pool
t = [0, 1, 2, 3, 4, 5]
def cube(x):
t[x] = x**3
pool = Pool(processes=4)
for i in range(6):
pool.apply_async(cube, args=(i, ))
for x in t:
print(x)
它并没有像我期望的那样真正改变t
。
我的真实代码就像:
from multiprocessing.pool import Pool
def func(a, b, c, d):
#some calculations
#save result to files
#no return value
lt = #list of possible value of a
#set values to b, c, d
p = Pool()
for i in lt:
p.apply_async(func, args=(i, b, c, d, ))
这里的问题在哪里?
谢谢!
更新:感谢评论和回答,现在我理解为什么我的简单例子不会起作用。但是,我的真实代码仍然存在问题。我已经检查过我的func
不依赖于任何全局变量,因此它似乎与我的示例代码不同。
根据建议,我向func
添加了返回值,现在我的代码是:
f = Flux("reactor")
d = Detector("Ge")
mv = arange(-6, 1.5, 0.5)
p = Pool()
lt = ["uee", "dee"]
for i in lt:
re = p.apply_async(res, args=(i, d, f, mv, ))
print(re.get())
p.close()
p.join()
现在我收到以下错误:
Traceback (most recent call last):
File "/Users/Shu/Documents/Programming/Python/Research/debug.py", line 35, in <module>
print(re.get())
File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/pool.py", line 608, in get
raise self._value
File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/pool.py", line 385, in _handle_tasks
put(task)
File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/connection.py", line 206, in send
self._send_bytes(_ForkingPickler.dumps(obj))
File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
AttributeError: Can't pickle local object 'Flux.__init__.<locals>.<lambda>'
答案 0 :(得分:1)
编辑:您提供的第一个示例由于一个简单的原因不起作用:进程不共享内存。因此,更改t[x] = x**3
不会应用于父进程,而会使列表t
的值保持不变。
您需要实际从计算中返回值并从中构建新列表。
def cube(x):
return x**3
t = [0, 1, 2, 3, 4, 5]
p = Pool()
t = p.map(cube, t)
print(t)
如果您在第二个示例中声明,结果不应该被返回但是要独立存储在文件中并且这不会发生,我建议检查函数的返回值以查看是否函数本身是否会引发异常。
我建议您获取实际结果,看看会发生什么:
p = Pool()
for i in lt:
res = p.apply_async(func, args=(i, b, c, d, ))
print(res.get()) # this will raise an exception if it happens within func
p.close() # do not accept any more tasks
p.join() # wait for the completion of all scheduled jobs
答案 1 :(得分:-1)
功能太快退出,请尝试在脚本末尾添加此代码:
import time
time.sleep(3)