我的代码在python中执行多处理器包的p.start()方法后,出现运行时错误。
记录的错误如下:
Traceback(上次调用):文件"Users/anujpanchal/Documents/exportify micro-booking/functionary/Notifications.py";,第396行,发送通知p.start()文件"Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/process.py";,第121行,起始自我_popen=自我_Popen(self)File"/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/context.py";,第224行,在_Popen中return _default_context.get_context().Process_Popen(Process_obj)文件"Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/context.py";,第284行,在_Popen中return Popen(process_obj)文件"/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/popen_spawn_posix.py";,第32行,在initsuper()中init(process_obj)文件"Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/popen_fork.py";,第19行,在initself中_launch(process_obj)File"/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/popen_spawn_posix.py";,第42行,在launch中prep_data=生成.get_preparation_data(process_obj_name)文件"Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/spown.py";,第154行,在get_preparation_data中_check_not_importing_main()文件"Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/spown.py";,第134行,在_check_not_importing_main中引发RuntimeError("RuntimeError:已尝试在当前进程已完成其引导阶段。
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.
在处理上述异常的过程中,发生了另一个异常:
Traceback(最后一次调用):File"&";,第1行,在文件"Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/spown.py";,第116行,spawn_mainexitcode=_main(fd,parent_tinel)文件"Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/spown.py";,第125行,in _mainprepare(preparation_data)File"/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/spown.py";,第236行,准备中_fixup_main_from_path(data[‘init_main_from _path’])文件"Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/spown.py";,第287行,在_fixup_main_from_path中main_content=runpy.run_path(main_path,文件"/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py";,第268行,在run_path中return _run_module_code(code,init_globals,run_name,文件"/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py";,run_module_code中的第97行_run_code(代码、mod_globals、init_globals,文件"/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py";,第87行,在_run_code中exec(code,run_globals)文件"/Users/anujpanchal/Documents/exportify micro-booking/functionary/Notifications.py";,第513行,在通知(checkpoint="discharged_on_transport")send_notification(booking_id="XPF100283";,tracking_obj=tracking_obj,scraper_update=False)文件"Users/anujpanchal/Documents/exportify micro-booking/functionary/Notifications.py";,第470行,在send_notification中return response.errorResponse("出现错误,请重试!")文件"Users/anujpanchal/Documents/exportify micro-booking/function/response.py";,第50行,错误响应return jsonify(response),status File"Users/anujpanchal/Documents/exportify micro-booking/venu/lib/python3.9/site packages/sflak/json/init.py";,第339行,在jsonify中如果current_app.config['JSONIFY_RETTYPRINT_REGULAR']或current_app.debug:文件"Users/anujpanchal/Documents/exportify micro-booking/venu/lib/python3.9/site packages/werkzeug/local.py";,第348行,在getattr中返回getattr(self.get_current_object(),name)File"Users/anujpanchal/Documents/exportify micro-booking/venu/lib/python3.9/site packages/werkzeug/local.py";,第307行,在_get_current_object中回归自我__local()文件"Users/anujpanchal/Documents/exportify micro-booking/venu/lib/python3.9/site packages/flank/globals.py";,第51行,在_find_app中引发运行时间错误(_app_ctx_err_msg)运行时间错误:在应用程序上下文之外工作。
这通常意味着您试图使用需要以某种方式与当前应用程序对象接口。要解决此问题,请使用app.app_context()设置一个应用程序上下文。有关详细信息,请参阅文档。
为什么会出现这种类型的运行时错误,是因为我将MacBook更新到了Big Sur 11.3,还是因为其他原因?
我对Mac不太了解。一般来说,我相信大多数版本都使用(或曾经使用)操作系统调用fork
来创建新进程。这意味着您不必将创建新进程的代码放在块中,例如。。。
if __name__ == '__main__':
这是使用操作系统调用spawn
来创建新进程的平台所需要的,原因是当使用spawn
时,通过初始化新的地址空间、启动新的Python解释器并从程序的最顶部重新运行代码来创建新的进程,从而在全局范围内重新执行代码。如果上述if
语句没有有条件地执行创建新进程的代码,这将导致在递归循环中无限次地重新执行该代码。
在Big Sur 11.3的更新中,创建新流程的新默认方法似乎从fork
切换到了spawn
——这可能是有充分理由的。所以我不太愿意建议你先打电话。。。
multiprocessig.set_start_method('fork')
以将CCD_ 7恢复为用于创建新进程的默认方法。
相反,我建议您将流程创建代码包含在前面提到的if
块中。真的很不幸,你决定不发布任何代码,否则我本可以向你展示如何做到这一点
我在运行以下代码时遇到了同样的问题:
import multiprocessing as mp
import time
from multiprocessing.sharedctypes import Value
def worker(sema, pool, resource):
name = mp.current_process().name
print("{}: Making pool active".format(name))
with sema:
pool.make_active(name)
print("{}: Waiting for 1 second".format(name))
time.sleep(1)
print("{}: Modifying resource".format(name))
resource.value = resource.value + 1
print("{}: Making pool inactive".format(name))
pool.make_inactive(name)
class ActivePool(object):
def __init__(self):
super(ActivePool, self).__init__()
self.manager = mp.Manager()
self.active = self.manager.list()
self.lock = mp.Lock()
def make_active(self, name):
with self.lock:
self.active.append(name)
def make_inactive(self, name):
with self.lock:
self.active.remove(name)
if __name__ == "__main__":
mp.set_start_method('fork')
pool = ActivePool()
sema = mp.Semaphore(3)
resource = Value('d', 10.0)
procs = []
for i in range(20):
proc_name = "process_{}".format(i)
p = mp.Process(target=worker, args=(sema, pool, resource,), name=proc_name)
procs.append(p)
for p in procs:
p.start()
for p in procs:
p.join()
print("Value of resource after modification: {}".format(resource.value))
在if循环中添加以下内容后,上面的代码工作了:
multiprocessig.set_start_method('fork')