Python多处理.传递ctype对象时,队列暂停



以下程序执行以下操作:

  1. 父进程创建数据类型为SHARED_DTYPE的进程间共享值
  2. 父进程创建进程间队列,以便将对象从子进程传递给父进程
  3. 父进程生成子进程(并等待对象通过进程间队列到达(
  4. 子进程修改进程间共享值的值
  5. 子进程创建数据类型为TRAVELLER_DTYPE的对象
  6. 子进程通过进程间队列传递创建的对象
  7. 父进程通过进程间队列接收对象
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类型,因此您可以使用intfloat,并且它有效。

我假设您在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

相关内容

  • 没有找到相关文章

最新更新