以下程序执行以下操作:
- 父进程创建数据类型为
SHARED_DTYPE
的进程间共享值 - 父进程创建进程间队列,以便将对象从子进程传递给父进程
- 父进程生成子进程(并等待对象通过进程间队列到达(
- 子进程修改进程间共享值的值
- 子进程创建数据类型为
TRAVELLER_DTYPE
的对象 - 子进程通过进程间队列传递创建的对象
- 父进程通过进程间队列接收对象
from multiprocessing import Value, Process, Queue
import ctypes
SHARED_DTYPE = ctypes.c_int
TRAVELLER_DTYPE = ctypes.c_float
shared_value = Value(SHARED_DTYPE, 0)
print('type of shared_value =', type(shared_value))
print('shared_value =', shared_value.value)
def child_proc():
try:
shared_value.value = 1
obj = TRAVELLER_DTYPE(5)
print('send into queue =', obj)
q.put(obj)
except BaseException as e:
print(e)
finally:
print('child_proc process is finished')
if __name__ == "__main__":
try:
q = Queue()
cp = Process(target=child_proc)
cp.start()
cp.join()
print('shared_value =', shared_value.value)
obj = q.get()
print('recv from queue =', obj)
except BaseException as e:
print(e)
finally:
print('__main__ process is finished')
现在,如果运行上述程序,它将正常工作,并给出以下输出:
type of shared_value = <class 'multiprocessing.sharedctypes.Synchronized'>
shared_value = 0
send into queue = c_float(5.0)
child_proc process is finished
shared_value = 1
recv from queue = c_float(5.0)
__main__ process is finished
但是,如果我们在程序顶部将TRAVELLER_DTYPE
更改为ctypes.c_int
,它将无法正常工作。
有时,它会给出以下输出:
type of shared_value = <class 'multiprocessing.sharedctypes.Synchronized'>
shared_value = 0
send into queue = c_int(5)
child_proc process is finished
shared_value = 1
^C <-- Pressed ctrl-C here, was hung indefinitely.
__main__ process is finished
而其他时候,它会给出以下输出:
type of shared_value = <class 'multiprocessing.sharedctypes.Synchronized'>
shared_value = 0
send into queue = c_int(5)
child_proc process is finished
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/queues.py", line 239, in _feed
obj = _ForkingPickler.dumps(obj)
File "/usr/lib/python3.8/multiprocessing/reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
File "/usr/lib/python3.8/multiprocessing/sharedctypes.py", line 129, in reduce_ctype
assert_spawning(obj)
File "/usr/lib/python3.8/multiprocessing/context.py", line 359, in assert_spawning
raise RuntimeError(
RuntimeError: c_int objects should only be shared between processes through inheritance
shared_value = 1
^C <-- Pressed ctrl-C here, was hung indefinitely.
__main__ process is finished
为什么
通常,程序正常工作,当且仅当SHARED_DTYPE != TRAVELLER_DTYPE
是否需要一些明确的锁定对象?
Python多处理文档页面没有提到任何此类问题。
在线搜索错误消息没有提供任何相关信息/线索:
- 一些SO问题
- 一些SO问题:没有共享值并一起排队,尽管建议使用
multiprocessing.Manager()
和multiprocessing.Manager().Queue()
- python错误报告:这里面有什么相关的东西可以提供一些提示吗
奇怪的是,当这两种类型不相同时,它会工作,但当它们相同时会失败。上面提到的错误报告看起来很相关,但很旧。这看起来确实是一个错误。一个解决方法是,与Value对象不同,Queue对象不需要(也许不应该(是ctypes
类型,因此您可以使用int
和float
,并且它有效。
我假设您在Linux上运行,但在Windows上,它使用进程的派生与分叉,通过派生,脚本被导入到子进程中,使全局变量在进程之间具有不同的实例。这甚至使您的";工作";场景在Windows上失败。相反,队列和共享值应作为参数传递给子工作进程,以确保它们作为同一对象正确继承(这可能是错误消息所指的(。
下面我还重新安排了代码,使其能够在Windows和Linux上工作:
from multiprocessing import Value, Process, Queue
import ctypes
SHARED_DTYPE = ctypes.c_int
TRAVELLER_DTYPE = int
def child_proc(q,shared_value):
shared_value.value = 1
obj = TRAVELLER_DTYPE(5)
print('send into queue =', obj)
q.put(obj)
print('child_proc process is finished')
if __name__ == "__main__":
shared_value = Value(SHARED_DTYPE, 0)
print('type of shared_value =', type(shared_value))
print('shared_value =', shared_value.value)
q = Queue()
cp = Process(target=child_proc,args=(q,shared_value))
cp.start()
cp.join()
print('shared_value =', shared_value.value)
obj = q.get()
print('recv from queue =', obj)
print('__main__ process is finished')
type of shared_value = <class 'multiprocessing.sharedctypes.Synchronized'>
shared_value = 0
send into queue = 5
child_proc process is finished
shared_value = 1
recv from queue = 5
__main__ process is finished