使用 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)
我提供的代码片段是作为多进程运行的脚本的一部分。因此,通过队列进行通信。当主应用程序关闭时,我想终止/终止搅拌机进程。由于主应用程序在关闭时等待“终止成功”消息,因此无法终止搅拌机进程会导致 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)
问题中提到的所有三个解决方案对于终止多进程都运行得非常好。问题在于不同进程之间的通信。由于多个进程在没有同步的情况下同时访问多处理队列,因此某些信号/消息未到达其假定的目的地。在这种情况下,特别是“kill”消息没有通过,因为主进程中的另一个循环检查队列是否已收到消息。问题是使用两个多处理事件(main_window_close 和 Blender_terminate)解决的,而不是依赖于同一个队列也用于其他通信:
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)