在Python多处理中,共享值是使用共享ctypes实现的。但这在 Windows 中不起作用,这里是示例代码和 Windows 错误消息。
问题:我们如何以在 Windows 中有效的方式做到这一点?
(请注意,我们使用多处理,因为 Python 线程实现在一个进程中运行它们)
#!/usr/bin/python
from multiprocessing import Process, Value
from time import sleep
def some_function( dummy, flag ):
while True:
if flag.value: break
sleep(1)
print( 'process - still running' )
print( 'process exit' )
some_flag = Value( 'i', 0 )
some_thread = Process( target = some_function, args=(0,some_flag) )
some_thread.start()
sleep( 5 )
some_flag.value = 1
some_thread.join( )
这是错误消息:
Exception has occurred: RuntimeError (note: full exception trace is shown but execution is paused at: <module>)
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if _name_ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
File "C:\Users\antoi\Downloads\multiprocessingdemo.py", line 17, in <module>
some_thread.start()
File "<string>", line 1, in <module> (Current frame)
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if _name_ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable
.
根据评论,您需要使用
import
习惯用法来保护您的脚本免受 if __name__ == "__main__":
的副作用。当使用“spawn”创建子进程时,这是需要的,因为“spawn”后,子进程将import
主文件来访问目标函数。在您的情况下,这可能会导致子级无限循环,从而创建更多子级(类似于叉子炸弹)。为了防止这种情况,python 会在导入子进程时检测到任何生成新进程的尝试,并抛出此错误。当使用“fork”创建子进程时不需要这样做,但这仅在基于 UNIX 的系统上可用。 Spawn 是 MacOS 的默认选项,而 Windows 则是only选项。
from multiprocessing import Process, Value
from time import sleep
def some_function( dummy, flag ):
while True:
if flag.value: break
sleep(1)
print( 'process - still running' )
print( 'process exit' )
if __name__ == "__main__":
some_flag = Value( 'i', 0 )
some_thread = Process( target = some_function, args=(0,some_flag) )
some_thread.start()
sleep( 5 )
some_flag.value = 1
some_thread.join( )
多年来,关于 “fork 与 spawn” 的讨论很多,如果您打算使用多处理,那么值得一读。