python multiprocessing Process with Manager 表现异常
python multiprocessing Process with Manager behave strangly
所以我得到了两个非常相似的 python 文件 A 和 B,只有微小的区别:死循环语句的地方。第一个引发异常,而第二个按预期工作。但是为什么?!
代码A:
import json
import multiprocessing
from time import sleep
def aaa(shared_data):
while True:
sleep(1)
shared_data["hello"] = "worldA"
print(json.dumps(shared_data.copy()))
def bbb(shared_data):
while True:
sleep(1)
shared_data["world"] = "helloB"
print(json.dumps(shared_data.copy()))
def run():
shared_data = multiprocessing.Manager().dict()
multiprocessing.Process(target=aaa, args=(shared_data, )).start()
multiprocessing.Process(target=bbb, args=(shared_data, )).start()
if __name__ == "__main__":
run()
while True:
pass
代码 B:
import json
import multiprocessing
from time import sleep
def aaa(shared_data):
while True:
sleep(1)
shared_data["hello"] = "worldA"
print(json.dumps(shared_data.copy()))
def bbb(shared_data):
while True:
sleep(1)
shared_data["world"] = "helloB"
print(json.dumps(shared_data.copy()))
def run():
shared_data = multiprocessing.Manager().dict()
multiprocessing.Process(target=aaa, args=(shared_data, )).start()
multiprocessing.Process(target=bbb, args=(shared_data, )).start()
while True:
pass
if __name__ == "__main__":
run()
为什么第一个 引发异常 而第二个 不?
第一个的输出,(除了异常之外什么都没有):
Process Process-3:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/managers.py", line 827, in _callmethod
conn = self._tls.connection
AttributeError: 'ForkAwareLocal' object has no attribute 'connection'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "foo.py", line 21, in bbb
shared_data["world"] = "hello" + str(cnt)
File "<string>", line 2, in __setitem__
File "/usr/lib/python3.8/multiprocessing/managers.py", line 831, in _callmethod
self._connect()
File "/usr/lib/python3.8/multiprocessing/managers.py", line 818, in _connect
conn = self._Client(self._token.address, authkey=self._authkey)
Process Process-2:
File "/usr/lib/python3.8/multiprocessing/connection.py", line 502, in Client
c = SocketClient(address)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 630, in SocketClient
s.connect(address)
FileNotFoundError: [Errno 2] No such file or directory
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/managers.py", line 827, in _callmethod
conn = self._tls.connection
AttributeError: 'ForkAwareLocal' object has no attribute 'connection'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "foo.py", line 12, in aaa
shared_data["hello"] = "world" + str(cnt)
File "<string>", line 2, in __setitem__
File "/usr/lib/python3.8/multiprocessing/managers.py", line 831, in _callmethod
self._connect()
File "/usr/lib/python3.8/multiprocessing/managers.py", line 818, in _connect
conn = self._Client(self._token.address, authkey=self._authkey)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 502, in Client
c = SocketClient(address)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 630, in SocketClient
s.connect(address)
FileNotFoundError: [Errno 2] No such file or directory
第二个输出(如预期):
{"hello": "worldA"}
{"hello": "worldA", "world": "helloB"}
{"hello": "worldA", "world": "helloB"}
{"hello": "worldA", "world": "helloB"}
{"hello": "worldA", "world": "helloB"}
{"hello": "worldA", "world": "helloB"}
{"hello": "worldA", "world": "helloB"}
{"hello": "worldA", "world": "helloB"}
...
我正在使用 Python 3.8.5 和 'Ubuntu 20.04.1 LTS (Focal Fossa)'。
已解决,原因是shared_data
在run
后被销毁,改成这样可以:
def run():
shared_data = multiprocessing.Manager().dict()
multiprocessing.Process(target=aaa, args=(shared_data, )).start()
multiprocessing.Process(target=bbb, args=(shared_data, )).start()
return shared_data
if __name__ == "__main__":
_ = run()
while True:
pass
所以我得到了两个非常相似的 python 文件 A 和 B,只有微小的区别:死循环语句的地方。第一个引发异常,而第二个按预期工作。但是为什么?!
代码A:
import json
import multiprocessing
from time import sleep
def aaa(shared_data):
while True:
sleep(1)
shared_data["hello"] = "worldA"
print(json.dumps(shared_data.copy()))
def bbb(shared_data):
while True:
sleep(1)
shared_data["world"] = "helloB"
print(json.dumps(shared_data.copy()))
def run():
shared_data = multiprocessing.Manager().dict()
multiprocessing.Process(target=aaa, args=(shared_data, )).start()
multiprocessing.Process(target=bbb, args=(shared_data, )).start()
if __name__ == "__main__":
run()
while True:
pass
代码 B:
import json
import multiprocessing
from time import sleep
def aaa(shared_data):
while True:
sleep(1)
shared_data["hello"] = "worldA"
print(json.dumps(shared_data.copy()))
def bbb(shared_data):
while True:
sleep(1)
shared_data["world"] = "helloB"
print(json.dumps(shared_data.copy()))
def run():
shared_data = multiprocessing.Manager().dict()
multiprocessing.Process(target=aaa, args=(shared_data, )).start()
multiprocessing.Process(target=bbb, args=(shared_data, )).start()
while True:
pass
if __name__ == "__main__":
run()
为什么第一个 引发异常 而第二个 不?
第一个的输出,(除了异常之外什么都没有):
Process Process-3:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/managers.py", line 827, in _callmethod
conn = self._tls.connection
AttributeError: 'ForkAwareLocal' object has no attribute 'connection'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "foo.py", line 21, in bbb
shared_data["world"] = "hello" + str(cnt)
File "<string>", line 2, in __setitem__
File "/usr/lib/python3.8/multiprocessing/managers.py", line 831, in _callmethod
self._connect()
File "/usr/lib/python3.8/multiprocessing/managers.py", line 818, in _connect
conn = self._Client(self._token.address, authkey=self._authkey)
Process Process-2:
File "/usr/lib/python3.8/multiprocessing/connection.py", line 502, in Client
c = SocketClient(address)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 630, in SocketClient
s.connect(address)
FileNotFoundError: [Errno 2] No such file or directory
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/managers.py", line 827, in _callmethod
conn = self._tls.connection
AttributeError: 'ForkAwareLocal' object has no attribute 'connection'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "foo.py", line 12, in aaa
shared_data["hello"] = "world" + str(cnt)
File "<string>", line 2, in __setitem__
File "/usr/lib/python3.8/multiprocessing/managers.py", line 831, in _callmethod
self._connect()
File "/usr/lib/python3.8/multiprocessing/managers.py", line 818, in _connect
conn = self._Client(self._token.address, authkey=self._authkey)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 502, in Client
c = SocketClient(address)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 630, in SocketClient
s.connect(address)
FileNotFoundError: [Errno 2] No such file or directory
第二个输出(如预期):
{"hello": "worldA"}
{"hello": "worldA", "world": "helloB"}
{"hello": "worldA", "world": "helloB"}
{"hello": "worldA", "world": "helloB"}
{"hello": "worldA", "world": "helloB"}
{"hello": "worldA", "world": "helloB"}
{"hello": "worldA", "world": "helloB"}
{"hello": "worldA", "world": "helloB"}
...
我正在使用 Python 3.8.5 和 'Ubuntu 20.04.1 LTS (Focal Fossa)'。
已解决,原因是shared_data
在run
后被销毁,改成这样可以:
def run():
shared_data = multiprocessing.Manager().dict()
multiprocessing.Process(target=aaa, args=(shared_data, )).start()
multiprocessing.Process(target=bbb, args=(shared_data, )).start()
return shared_data
if __name__ == "__main__":
_ = run()
while True:
pass