在Python中,如果我将一个普通变量传递给一个函数并使用apply\u async在多个进程中执行它,会发生什么?
我遇到了一些Python多处理的行为,我无法理解 例如:在Python中,如果我将一个普通变量传递给一个函数并使用apply\u async在多个进程中执行它,会发生什么?,python,operating-system,multiprocessing,Python,Operating System,Multiprocessing,我遇到了一些Python多处理的行为,我无法理解 例如: from multiprocessing import Pool import time import sys def f(x): time.sleep(10) print(x) return x * x def f2(x, f): time.sleep(10) print(x, file=f) return x * x if __name__ == '__main__': p
from multiprocessing import Pool
import time
import sys
def f(x):
time.sleep(10)
print(x)
return x * x
def f2(x, f):
time.sleep(10)
print(x, file=f)
return x * x
if __name__ == '__main__':
p = Pool(5)
for t in range(10):
p.apply_async(f, args=(t,))
p.close()
p.join() # Here it blocks and prints the number, which is normal.
p = Pool(5)
for t in range(10):
p.apply_async(f2, args=(t, sys.stdout))
p.close()
p.join() # Here it does not block and nothing happends(no output at all)...
输出为:
3
1
0
2
4
5
9
6
7
8
我知道在使用多处理和
apply\u async
时,我们必须使用共享变量之类的东西传递给函数,但是如果我将普通变量传递给apply\u async
中使用的函数,会发生什么情况?多处理.Pool
在单独的进程中执行您的逻辑。如果逻辑引发异常,池将把它返回给调用者
在代码中,您没有收集函数的输出,因此没有注意到真正的问题
尝试按如下方式修改代码:
p = Pool(5)
for t in range(10):
task = p.apply_async(f2, args=(t, sys.stdout))
task.get()
然后,您将获得在f2
中引发的实际异常:
Traceback (most recent call last):
File "asd.py", line 24, in <module>
p.apply_async(f2, args=(t, sys.stdout)).get()
File "/usr/lib/python3.5/multiprocessing/pool.py", line 608, in get
raise self._value
File "/usr/lib/python3.5/multiprocessing/pool.py", line 385, in _handle_tasks
put(task)
File "/usr/lib/python3.5/multiprocessing/connection.py", line 206, in send
self._send_bytes(ForkingPickler.dumps(obj))
File "/usr/lib/python3.5/multiprocessing/reduction.py", line 50, in dumps
cls(buf, protocol).dump(obj)
TypeError: cannot serialize '_io.TextIOWrapper' object
回溯(最近一次呼叫最后一次):
文件“asd.py”,第24行,在
p、 apply_async(f2,args=(t,sys.stdout)).get()
get中第608行的文件“/usr/lib/python3.5/multiprocessing/pool.py”
提升自我价值
文件“/usr/lib/python3.5/multiprocessing/pool.py”,第385行,在任务处理中
放置(任务)
文件“/usr/lib/python3.5/multiprocessing/connection.py”,第206行,在send中
self.\u发送字节(ForkingPickler.dumps(obj))
文件“/usr/lib/python3.5/multiprocessing/reduce.py”,第50行,转储
cls(buf,协议).dump(obj)
TypeError:无法序列化'\u io.TextIOWrapper'对象
结果是,sys.stdout
不是。在本例中,这不是一个问题,因为每个进程都是唯一的。您可以避免将其传递给函数,而只需在f2
中使用它