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
相关产品推荐
相关产品推荐

