如何在Python中通过按键立即终止含循环的多进程/线程程序?
解决按下P键立即终止Python程序的问题
问题根源
原代码存在两个导致关闭缓慢的核心问题:
- Loop B是独立的子进程,Loop A线程仅自身
break无法终止该进程 - Loop B中的
time.sleep(2)会让进程进入休眠状态,此时无法立即响应终止请求;另外pyautogui.locateOnScreen的检测过程也可能产生耗时延迟
方案1:强制终止进程(最快关闭)
通过保存子进程实例,按下P键时直接强制终止Loop B进程,再退出整个程序:
import keyboard import time import pyautogui from multiprocessing import Process from threading import Thread import sys # 全局保存Loop B的进程实例 loop_b_process = None def loop_a(): global loop_b_process while True: key = keyboard.read_key() if key == 'p': print('Program has stopped...') # 立即终止Loop B进程 if loop_b_process and loop_b_process.is_alive(): loop_b_process.terminate() loop_b_process.join() # 等待进程彻底释放资源 sys.exit() # 退出整个程序 else: print("Wrong key champ !") time.sleep(0.5) def loop_b(): while True: if pyautogui.locateOnScreen('image.png', confidence=0.5) is not None: print("I can see it") else: print("I am unable to see it") time.sleep(2) if __name__ == '__main__': loop_b_process = Process(target=loop_b) loop_b_process.start() Thread(target=loop_a).start()
修改说明:
- 全局变量
loop_b_process让Loop A线程能直接访问并操作子进程 terminate()会强制终止Loop B进程,无视其当前执行状态,实现立即关闭join()确保进程资源被彻底释放,避免残留sys.exit()直接退出主程序,清除所有线程和进程
方案2:优雅终止进程(推荐)
如果不想强制终止进程,可通过multiprocessing.Event实现进程间通信,让Loop B主动检测终止信号:
import keyboard import time import pyautogui from multiprocessing import Process, Event from threading import Thread import sys # 进程间共享的终止事件 stop_event = Event() def loop_a(): while True: key = keyboard.read_key() if key == 'p': print('Program has stopped...') stop_event.set() # 设置终止信号 sys.exit() else: print("Wrong key champ !") time.sleep(0.5) def loop_b(): while not stop_event.is_set(): if pyautogui.locateOnScreen('image.png', confidence=0.5) is not None: print("I can see it") else: print("I am unable to see it") # 用wait替代sleep,事件触发时立即唤醒 stop_event.wait(2) if __name__ == '__main__': loop_b_process = Process(target=loop_b) loop_b_process.start() Thread(target=loop_a).start()
修改说明:
stop_event是进程间共享的信号标记,Loop B每次循环都会检查其状态stop_event.wait(2)替代time.sleep(2),当终止信号被设置时,进程会立即从等待状态唤醒,无需等到2秒结束- 这种方式让Loop B在当前循环结束后主动退出,既保证了响应速度,又避免了强制终止可能带来的资源泄漏
内容的提问来源于stack exchange,提问作者Blockhead01
相关产品推荐
相关产品推荐

