Python threading线程使用keyboard库时出现阻塞问题如何解决?
问题根源
keyboard.write()执行时会模拟真实键盘的按下、抬起动作,本身自带毫秒级的执行耗时,无间隔连续调用时会几乎占满子线程的执行时间,导致keyboard.is_pressed("F9")的轮询检测频率极低,很难捕获到按下F9的瞬间状态。- 原脚本没有给连发动作加间隔,极端情况下内层循环一轮99%的时间都在执行
keyboard.write(),只有极短的时间窗口执行按键检测,自然容易漏判F9按下的状态。你之前用print时没有问题,就是因为print的执行耗时远低于keyboard.write,轮询检测的频率足够捕获按键状态。
修复方案
方案1:最小改动适配原有逻辑
只需要在内层连发循环里加短时间睡眠,让出线程时间给按键检测即可,同时用time模块做防抖,逻辑更简洁:
import keyboard import threading import time def spam_this(): status = 0 while True: if keyboard.is_pressed("F9") and status == 0: status = 1 time.sleep(0.2) # 按键防抖,避免单次按下被识别为多次触发 if keyboard.is_pressed("F9") and status == 1: status = 0 time.sleep(0.2) while status == 1: if keyboard.is_pressed("F9") and status == 1: status = 0 time.sleep(0.2) break keyboard.write("test") time.sleep(0.05) # 核心修改:让出执行时间给按键检测,同时可自行调整数值控制连发速度 threading.Thread(target=spam_this).start()
方案2:改用热键回调机制(更稳定,不受阻塞影响)
不使用轮询检测按键,直接注册全局热键切换状态,完全避免漏判问题:
import keyboard import threading import time spam_status = False # 热键触发回调,直接切换连发状态 def toggle_spam(): global spam_status spam_status = not spam_status def spam_task(): while True: if spam_status: keyboard.write("test") time.sleep(0.05) # 注册F9为切换热键,suppress=True避免F9按键输入被打入当前窗口 keyboard.add_hotkey("F9", toggle_spam, suppress=True) threading.Thread(target=spam_task, daemon=True).start() # 阻塞主线程保持脚本运行 keyboard.wait()
内容的提问来源于stack exchange,提问作者user16053699
相关产品推荐
相关产品推荐

