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

Python Thread线程未执行类方法hear()的问题排查

问题原因与修复方案
  • 核心问题:模块引用被覆盖
    你开头用import speech_recognition as sr将语音识别库导入并设置别名为sr,但在主入口处写了sr=SpeechRecognizer(),直接把全局作用域的sr从模块对象替换成了自定义类的实例。子线程执行hear()方法走到with sr.Microphone()时,sr已经不是原语音识别库,会抛出AttributeError导致子线程异常终止,如果没注意控制台的异常栈,很容易误以为子线程没调用hear()。
  • 停止逻辑失效
    用标志位控制线程退出的思路没问题,但speech_recognizer.listen()是阻塞调用,默认会一直等待麦克风输入不会主动返回。哪怕主线程把HEAR设为False,子线程也会卡在等待音频输入的逻辑里,走不到下一次while条件判断,最终导致stop()里的join()永久卡死。
  • 类变量使用不规范
    你把HEAR开关、识别器实例都定义成了类变量,所有类实例会共享这两个属性,单实例运行暂时无异常,但多实例场景下会出现状态互相干扰的问题。

修复后代码

import speech_recognition as sr
from threading import Thread
import time

class SpeechRecognizer():
    def __init__(self,src_lang='hi-IN'):
        self.src_lang=src_lang
        # 开关和识别器改为实例变量,避免多实例共享状态
        self.HEAR = True
        self.speech_recognizer = sr.Recognizer()
        # 设为守护线程,避免主线程意外退出时残留线程
        self.hearing_thread = Thread(target=self.hear, daemon=True)

    def hear(self):
        print('in hearing', flush=True)
        with sr.Microphone() as source:
            self.speech_recognizer.adjust_for_ambient_noise(source)
            while self.HEAR:
                try:
                    # 增加1秒等待超时,定期回到循环检查退出标志
                    # phrase_time_limit限制单句最长识别时长,避免长时间阻塞
                    audio = self.speech_recognizer.listen(source, timeout=1, phrase_time_limit=10)
                    text = self.speech_recognizer.recognize_google(audio, language=self.src_lang)
                    print(text)
                except sr.WaitTimeoutError:
                    # 等待音频超时,直接进入下一轮循环
                    continue
                except Exception as e:
                    print(f"识别异常: {str(e)}")
                    continue

    def start(self):
        print('starting to hear')
        self.hearing_thread.start()

    def stop(self):
        self.HEAR = False
        self.hearing_thread.join()
        print('done hearing')

if __name__=='__main__':
    # 实例改名,避免覆盖导入的sr模块引用
    recognizer = SpeechRecognizer()
    recognizer.start()
    for i in range(5):
        time.sleep(1)
    recognizer.stop()

内容的提问来源于stack exchange,提问作者yashaswini srirangarajan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 10:12:23