You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多线程语音识别主循环失效问题求助

Python语音识别程序阻塞问题修复

问题描述

我正在开发一款Python语音识别程序,需求如下:

  • 说出"above"时,程序持续执行按下向下键的操作;再次说出"above"时,停止该操作。
  • 其他语音指令(如"after"、"before"等)需要正常响应。

当前遇到的问题:

  • 加入threading让语音识别持续运行后,主循环被持续按向下键的逻辑卡住,无法识别新的语音结果。
  • 移除threading后,除了按下向下键的循环无法停止外,其余功能正常。

原代码:

from speech import *
import queue
import threading
import pyautogui
import keyboard
import time
import sys

def speech_func(res_queue):
    while True:
        res = speech()
        res_queue.put(res)

res_queue = queue.Queue()
prc=threading.Thread(target=speech_func, args=(res_queue,))
prc.start()

flower_active=False

while True:
    res = res_queue.get()
    
    if "above" in res:
        flower_active = not flower_active

    while flower_active:
        keyboard.press_and_release('down')
        time.sleep(0.1)

    if "after" in res:
        pyautogui.moveTo(1010,130)
        pyautogui.click()

    if "before" in res:
        pyautogui.moveTo(890,130)
        pyautogui.click()

    if "music" in res:
        pyautogui.moveTo(1680,130)
        pyautogui.click()
                         
    if "below" in res:
        keyboard.press_and_release('pageup')

    if "ending" in res:
        prc.join()
        sys.exit(0)

问题分析

核心问题在于主循环中的while flower_active:是阻塞式循环——一旦flower_active设为True,主线程会一直卡在这个循环里,无法去队列中获取新的语音识别结果,导致后续的语音指令(包括再次触发"above"停止操作)都无法被处理。

修复方案

把持续按向下键的逻辑放到单独的线程中执行,主循环只负责处理语音结果、控制标志位,避免阻塞主流程。同时通过标志位让线程自行响应启停信号。

修改后的代码:

from speech import *
import queue
import threading
import pyautogui
import keyboard
import time
import sys

def speech_func(res_queue):
    while True:
        res = speech()
        res_queue.put(res)

# 封装持续按向下键的线程逻辑
def press_down_loop():
    while flower_active:
        keyboard.press_and_release('down')
        time.sleep(0.1)

res_queue = queue.Queue()
# 设置语音识别线程为守护线程,主程序退出时自动结束
prc = threading.Thread(target=speech_func, args=(res_queue,))
prc.daemon = True
prc.start()

flower_active = False
down_thread = None

while True:
    res = res_queue.get()
    
    if "above" in res:
        flower_active = not flower_active
        if flower_active:
            # 启动新线程执行按键操作
            down_thread = threading.Thread(target=press_down_loop)
            down_thread.daemon = True
            down_thread.start()
        # 无需手动终止线程,flower_active变为False后线程会自行退出循环
        
    if "after" in res:
        pyautogui.moveTo(1010,130)
        pyautogui.click()

    if "before" in res:
        pyautogui.moveTo(890,130)
        pyautogui.click()

    if "music" in res:
        pyautogui.moveTo(1680,130)
        pyautogui.click()
                         
    if "below" in res:
        keyboard.press_and_release('pageup')

    if "ending" in res:
        flower_active = False  # 确保按键线程停止
        if down_thread and down_thread.is_alive():
            down_thread.join(timeout=1)  # 等待线程结束,超时1秒
        sys.exit(0)

关键改动说明

  • 将持续按键逻辑封装为独立线程函数,通过flower_active标志位控制循环启停。
  • 启动按键线程时设置为守护线程,确保主程序退出时线程自动结束,避免残留。
  • 主循环仅负责处理语音指令、切换标志位,不再执行阻塞性操作,保证能持续响应新的语音结果。

内容的提问来源于stack exchange,提问作者Piyush Mandal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 09:23:09