提问人:MasterOfDesaster42 提问时间:9/27/2023 最后编辑:MasterOfDesaster42 更新时间:9/28/2023 访问量:80
使用 pyinstaller 构建 .exe 后无法终止或终止子进程
Cannot terminate or kill subprocess after building .exe with pyinstaller
问:
在使用 python 执行脚本时,以我下面描述的方式终止以下子进程非常有效。但是,使用 pyinstaller 构建 .exe 文件后,blender 进程不会终止。
bpy_script_path = os.path.join(main_dir, 'Packages', 'Scripts', 'BlenderRendering', 'bpy_script.py')
blender_command = [blender_executable, '--background','--python', bpy_script_path]
if os.name == 'nt':
CREATE_NO_WINDOW = 0x08000000
blender_process = subprocess.Popen(blender_command, creationflags = CREATE_NO_WINDOW)
else:
blender_process = subprocess.Popen(blender_command)
while blender_process.poll() == None:
try:
msg = queue.get_nowait()
if msg[0] == 'kill':
#tried first
blender_process.kill()
blender_process.wait()
#tried second
blender_process.terminate()
blender_process.wait()
#tried third
subprocess.call(['taskkill', '/F', '/T', '/PID', str(blender_process.pid)])
queue.put(('kill successful', None, None))
return False
except:
pass
time.sleep(1)
我提供的代码片段是作为多进程运行的脚本的一部分。因此,通过队列进行通信。我想在主应用程序关闭时终止/终止搅拌机进程。由于主应用程序在关闭时等待“kill successful”消息,因此无法终止 blender 进程会导致main_window在循环中运行,等待成功终止的消息。我也尝试使用 psutil,但这也不起作用。不知道此时该怎么做。.
while blender_process.poll() == None:
msg = None
try:
msg = queue.get_nowait()
except:
pass
if msg:
if msg[0] == 'kill':
subprocess.call(['taskkill', '/F', '/T', '/PID', str(blender_process.pid)])
queue.put(('kill successful', None, None))
return False
time.sleep(1)
答:
0赞
MasterOfDesaster42
9/28/2023
#1
问题中提到的所有三种解决方案都非常适合终止多进程。问题在于不同进程之间的沟通。由于多个进程在没有同步的情况下同时访问多处理队列,因此某些信号/消息未到达其假定的目的地。特别是在这种情况下,“kill”消息没有通过,因为主进程中的另一个循环检查队列已经收到消息。使用两个多处理事件(main_window_close 和 blender_terminated)解决了该问题,而不是依赖于也用于其他通信的同一队列:
while blender_process.poll() == None:
if main_window_close.is_set():
blender_process.terminate()
blender_process.wait()
blender_terminated.set()
return False
time.sleep(1)
评论
try: except: pass