【发布时间】:2020-12-01 13:46:03
【问题描述】:
以下程序执行以下操作:
- 父进程创建数据类型
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 多处理 doc page 没有提到任何此类问题。
在线搜索错误消息并没有提供任何相关信息/线索:
- Some SO question
-
Some SO question:没有共享值和队列在一起,虽然建议使用
multiprocessing.Manager()和multiprocessing.Manager().Queue() - A python bug report:这里面有什么相关的东西可以提供一些提示吗?
【问题讨论】:
标签: python multiprocessing queue ctypes