Linux和Windows之间的多处理输出不同 - 为什么?

And*_*ndy 9 python linux windows attributeerror python-multiprocessing

我试图将共享秘密传递给子进程.在Linux环境中,这可行.在Windows环境中,孩子不会收到共享密钥.下面的三个文件是我正在尝试做的一个简单示例:

main.py

import multiprocessing
import module1
import module2

if __name__ == "__main__":
    module1.init()
    process = multiprocessing.Process(target=module2.start)
    process.start()
    process.join()
Run Code Online (Sandbox Code Playgroud)

module1.py

import ctypes
import multiprocessing

x = None

def init():
    global x
    x = multiprocessing.Value(ctypes.c_wchar_p, "asdf")
Run Code Online (Sandbox Code Playgroud)

module2.py

import module1

def start():
    print(module1.x.value)
Run Code Online (Sandbox Code Playgroud)

在Ubuntu 14.04环境中,在Python 3.5上,我收到以下输出:

$ python3 main.py
asdf
Run Code Online (Sandbox Code Playgroud)

在CentOS 7环境中,我收到以下输出:

$ python3 main.py
asdf
Run Code Online (Sandbox Code Playgroud)

在Windows 10上使用Windows子系统Linux(在创建者更新之前和之后,所以Ubuntu 14.04和16.04)我得到以下输出:

$ python3 main.py
asdf
Run Code Online (Sandbox Code Playgroud)

但是,在Windows 7和Windows 10环境中,使用3.5或3.6,我得到的AttributeError不是上面的输出:

Process Process-1:
Traceback (most recent call last):
  File "C:\Python\Python35\lib\multiprocessing\process.py", line 249, in _bootstrap
    self.run()
  File "C:\Python\Python35\lib\multiprocessing\process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "H:\Development\replicate-bug\module2.py", line 5, in start
    print(module1.x.value)
AttributeError: 'NoneType' object has no attribute 'value'
Run Code Online (Sandbox Code Playgroud)

我正在使用共享的ctype.该值应由子进程继承.

为什么我AttributeError在Windows环境中收到此信息,而不是Linux环境?

Vog*_*612 4

正如侧边栏上自动链接的一篇文章中提到的,Windowsfork在 *NIX 系统上没有系统调用。

这意味着 Windows 子进程基本上是完全独立的,而不是共享全局状态(就像 NIX 进程所做的那样)。这包括模块。

怀疑正在发生的事情是模块被重新加载,并且module1您访问的内部module2.start并不完全是您期望的模块。

多处理指南明确提到模块级常量不受规则的约束:“变量可能不包含您期望的内容”。无论哪种情况,解决方案都是显式地将所需的模块传递给子进程,如下所示:

模块2

def start(mod1):
    print(mod1.x.value)
Run Code Online (Sandbox Code Playgroud)

主要.py

if __name__ == '__main__':
    module1.init()
    process = multiprocessing.Process(target=module2.start, args=(module1,))
    process.start()
    process.join()
Run Code Online (Sandbox Code Playgroud)