Linux 和 Windows 之间的多处理输出不同 - 为什么?
Multiprocessing output differs between Linux and Windows - Why?
我正在尝试将共享机密传递给 child 进程。在 Linux 环境中这有效。在 Windows 环境中,child 不会收到共享密钥。下面的三个文件是我正在尝试做的一个简单示例:
main.py
import multiprocessing
import module1
import module2
if __name__ == "__main__":
module1.init()
process = multiprocessing.Process(target=module2.start)
process.start()
process.join()
module1.py
import ctypes
import multiprocessing
x = None
def init():
global x
x = multiprocessing.Value(ctypes.c_wchar_p, "asdf")
module2.py
import module1
def start():
print(module1.x.value)
在 Ubuntu 14.04 环境中,在 Python 3.5 上,我收到以下输出:
$ python3 main.py
asdf
在 CentOS 7 环境中,我收到以下输出:
$ python3 main.py
asdf
在 Windows 10 上使用 Linux 的 Windows 子系统(在创作者更新之前和之后,所以 Ubuntu 14.04 和 16.04)我得到以下输出:
$ python3 main.py
asdf
但是,在 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'
我正在使用 shared ctype。该值应由 child 进程继承。
为什么我在 Windows 环境中收到此 AttributeError
,而不是 Linux 环境?
如其中一篇帖子 所述,windows 在 *NIX 系统上没有 fork
系统调用。
这意味着 Windows 子进程基本上是完全独立的,而不是共享全局状态(就像 NIX 进程可以做的那样)。这包括模块。
我怀疑发生的是模块被重新加载并且您在 module2.start
中访问的 module1
并不完全是您期望的模块.
multiprocessing guidelines 明确提到模块级常量不受规则约束:"variables may not contain what you expect"。那么在任何一种情况下,解决方案都是将您想要的模块显式传递给子进程,如下所示:
模块 2
def start(mod1):
print(mod1.x.value)
main.py
if __name__ == '__main__':
module1.init()
process = multiprocessing.Process(target=module2.start, args=(module1,))
process.start()
process.join()
我正在尝试将共享机密传递给 child 进程。在 Linux 环境中这有效。在 Windows 环境中,child 不会收到共享密钥。下面的三个文件是我正在尝试做的一个简单示例:
main.py
import multiprocessing
import module1
import module2
if __name__ == "__main__":
module1.init()
process = multiprocessing.Process(target=module2.start)
process.start()
process.join()
module1.py
import ctypes
import multiprocessing
x = None
def init():
global x
x = multiprocessing.Value(ctypes.c_wchar_p, "asdf")
module2.py
import module1
def start():
print(module1.x.value)
在 Ubuntu 14.04 环境中,在 Python 3.5 上,我收到以下输出:
$ python3 main.py
asdf
在 CentOS 7 环境中,我收到以下输出:
$ python3 main.py
asdf
在 Windows 10 上使用 Linux 的 Windows 子系统(在创作者更新之前和之后,所以 Ubuntu 14.04 和 16.04)我得到以下输出:
$ python3 main.py
asdf
但是,在 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'
我正在使用 shared ctype。该值应由 child 进程继承。
为什么我在 Windows 环境中收到此 AttributeError
,而不是 Linux 环境?
如其中一篇帖子 fork
系统调用。
这意味着 Windows 子进程基本上是完全独立的,而不是共享全局状态(就像 NIX 进程可以做的那样)。这包括模块。
我怀疑发生的是模块被重新加载并且您在 module2.start
中访问的 module1
并不完全是您期望的模块.
multiprocessing guidelines 明确提到模块级常量不受规则约束:"variables may not contain what you expect"。那么在任何一种情况下,解决方案都是将您想要的模块显式传递给子进程,如下所示:
模块 2
def start(mod1):
print(mod1.x.value)
main.py
if __name__ == '__main__':
module1.init()
process = multiprocessing.Process(target=module2.start, args=(module1,))
process.start()
process.join()