【发布时间】:2020-03-07 15:54:34
【问题描述】:
我试图了解并发性一般是如何工作的,在这种情况下,它是如何在 Python 中具体工作的。
我使用inputs 库已经有一段时间了,并且在使用它生成进程时总是不得不“作弊” - 使用subprocess.Popen 执行脚本。今天,我不假思索地将一行代码放在了不同的地方,并成功地生成了一个针对函数的Process。但我不明白为什么它会起作用......
以下代码公开了两个简单的类,一个在 self 中包含对controller 的引用,而另一个没有(并使用模块中声明的全局引用):
import inputs
import multiprocessing
import time
controller = inputs.devices.gamepads[0]
class TestBroken:
def __init__(self):
self.controller = controller
def read(self):
while True:
ev = self.controller.read()[0]
print(ev.code, ev.state)
class TestWorking:
def read(self):
while True:
ev = controller.read()[0]
print(ev.code, ev.state)
if __name__ == '__main__':
t = TestWorking()
# Uncomment the line below to get the errors
#t = TestBroken()
multiprocessing.Process(target=t.read).start()
while True:
print("I'm alive!")
time.sleep(1)
取消注释#t = TestBroken()后的错误如下:
Traceback (most recent call last):
File "C:/Coding/...", line 31, in <module>
multiprocessing.Process(target=t.read).start()
File "C:\Python\lib\multiprocessing\process.py", line 121, in start
self._popen = self._Popen(self)
File "C:\Python\lib\multiprocessing\context.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:\Python\lib\multiprocessing\context.py", line 326, in _Popen
return Popen(process_obj)
File "C:\Python\lib\multiprocessing\popen_spawn_win32.py", line 93, in __init__
reduction.dump(process_obj, to_child)
File "C:\Python\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'CDLL.__init__.<locals>._FuncPtr'
我不太明白存储对对象的引用如何使pickle 变得疯狂,同时允许在模块级别存储相同的引用。我恳请您协助揭开这个问题背后的奥秘。
【问题讨论】:
标签: python python-3.x serialization multiprocessing pickle