已尝试在当前进程在 python 中完成其引导阶段之前启动新进程
An attempt has been made to start a new process before the current process has finished its bootstrapping phase in python
我尝试 运行 此代码 python
import multiprocessing
manager = multiprocessing.Manager()
final_list = manager.list()
input_list_one = ['one', 'two', 'three', 'four', 'five']
input_list_two = ['six', 'seven', 'eight', 'nine', 'ten']
def worker(data):
for item in data:
final_list.append(item)
if __name__ == '__main__':
process1 = multiprocessing.Process(target=worker, args=[input_list_one])
process2 = multiprocessing.Process(target=worker, args=[input_list_two])
process1.start()
process2.start()
process1.join()
process2.join()
print(final_list)
但是出现了这个错误:
运行时错误:
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.
语句有问题:
manager = multiprocessing.Manager()
它通过启动服务器进程发挥其“魔力”。因此,此语句需要与托管列表的创建一起移动到 if __name__ = '__main__':
块内,现在需要将其作为附加参数传递给流程函数 worker
。事实上,为了提高效率,您还不如移动全局范围内的所有声明,这些声明实际上并不需要存在于 if __name__ = '__main__':
块中,否则它们将被创建的每个新进程不必要地执行。
import multiprocessing
def worker(final_list, data):
for item in data:
final_list.append(item)
if __name__ == '__main__':
manager = multiprocessing.Manager()
final_list = manager.list()
input_list_one = ['one', 'two', 'three', 'four', 'five']
input_list_two = ['six', 'seven', 'eight', 'nine', 'ten']
process1 = multiprocessing.Process(target=worker, args=[final_list, input_list_one])
process2 = multiprocessing.Process(target=worker, args=[final_list, input_list_two])
process1.start()
process2.start()
process1.join()
process2.join()
print(final_list)
打印:
['six', 'seven', 'eight', 'nine', 'one', 'ten', 'two', 'three', 'four', 'five']
让我详细说明一下我的回答:
您显然 运行正在使用 spawn
方法创建新进程的平台上。这意味着要启动一个新进程,将创建一个新的空地址 space,并且 Python 解释器的一个新实例是针对源的 运行。在调用您的 Process
实例的 target 之前,将首先执行源文件中位于全局范围内的任何语句来初始化进程, 除了if __name__ = '__main__':
块 中的任何语句(因为对于新进程,__name__
值将不是“__main__”)。这就是为什么您需要将创建新进程的代码放在这样的块中,即避免进入创建新进程的递归循环 ad infinitum 如果未检测到。在你的情况下,它并没有被检测到,你得到了你看到的错误消息。
但是即使创建 Manager
实例没有导致创建新进程,您的程序也不会正确。在全局范围内使用语句 final_list = manager.list()
意味着 运行ning 程序中的所有三个进程都将访问 final_list
.
的三个不同实例
我尝试 运行 此代码 python
import multiprocessing
manager = multiprocessing.Manager()
final_list = manager.list()
input_list_one = ['one', 'two', 'three', 'four', 'five']
input_list_two = ['six', 'seven', 'eight', 'nine', 'ten']
def worker(data):
for item in data:
final_list.append(item)
if __name__ == '__main__':
process1 = multiprocessing.Process(target=worker, args=[input_list_one])
process2 = multiprocessing.Process(target=worker, args=[input_list_two])
process1.start()
process2.start()
process1.join()
process2.join()
print(final_list)
但是出现了这个错误: 运行时错误:
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.
语句有问题:
manager = multiprocessing.Manager()
它通过启动服务器进程发挥其“魔力”。因此,此语句需要与托管列表的创建一起移动到 if __name__ = '__main__':
块内,现在需要将其作为附加参数传递给流程函数 worker
。事实上,为了提高效率,您还不如移动全局范围内的所有声明,这些声明实际上并不需要存在于 if __name__ = '__main__':
块中,否则它们将被创建的每个新进程不必要地执行。
import multiprocessing
def worker(final_list, data):
for item in data:
final_list.append(item)
if __name__ == '__main__':
manager = multiprocessing.Manager()
final_list = manager.list()
input_list_one = ['one', 'two', 'three', 'four', 'five']
input_list_two = ['six', 'seven', 'eight', 'nine', 'ten']
process1 = multiprocessing.Process(target=worker, args=[final_list, input_list_one])
process2 = multiprocessing.Process(target=worker, args=[final_list, input_list_two])
process1.start()
process2.start()
process1.join()
process2.join()
print(final_list)
打印:
['six', 'seven', 'eight', 'nine', 'one', 'ten', 'two', 'three', 'four', 'five']
让我详细说明一下我的回答:
您显然 运行正在使用 spawn
方法创建新进程的平台上。这意味着要启动一个新进程,将创建一个新的空地址 space,并且 Python 解释器的一个新实例是针对源的 运行。在调用您的 Process
实例的 target 之前,将首先执行源文件中位于全局范围内的任何语句来初始化进程, 除了if __name__ = '__main__':
块 中的任何语句(因为对于新进程,__name__
值将不是“__main__”)。这就是为什么您需要将创建新进程的代码放在这样的块中,即避免进入创建新进程的递归循环 ad infinitum 如果未检测到。在你的情况下,它并没有被检测到,你得到了你看到的错误消息。
但是即使创建 Manager
实例没有导致创建新进程,您的程序也不会正确。在全局范围内使用语句 final_list = manager.list()
意味着 运行ning 程序中的所有三个进程都将访问 final_list
.