我如何暂停一个线程,直到另一个线程在python中停止其动作?

时间:2019-12-27 14:42:51

标签: python-3.x multithreading speech-recognition pyttsx

我有两个线程同时运行,speechRecognitionspeakBack。这两个线程都在while循环(while True: #do something)中运行。 语音识别一直在等待麦克风输入。然后,一旦收到,它将语音输入的文本版本保存到文件中,该文件由我的第二个线程speakBack加载,并通过扬声器讲话。 我的问题是,当通过扬声器说出该短语时,它会被麦克风拾取,然后进行翻译,然后再次保存到此文件中进行处理,从而导致无休止的循环。

我如何使speechRecognition线程挂起自身,等待speakBack线程停止通过扬声器输出声音,然后继续收听下一个语音输入? 我分别使用了SpeechRecognition库和pyttsx3库进行语音识别和语音输出。

1 个答案:

答案 0 :(得分:0)

执行此操作的方法是在线程之间具有共享状态(使用线程可以存储并从中读取的全局变量来指示其进度,或者使用传递给每个线程的可变引用)。我将在下面提供的解决方案涉及一个存储可变引用的全局变量,但是您可以轻松地将队列传递到两个线程中,而不是将其全局存储。

使用队列是在python中的线程之间传递消息的一种非常标准的方法,因为队列已经以线程安全的方式编写,因此不必考虑同步和锁定。此外,对queue.get的阻塞调用的实现方式不涉及在while循环中重复而浪费地检查条件变量。

以下是某些代码的外观:

import queue

START_SPEAK_BACK = 0
START_SPEECH_RECOGNITION = 1
messageQueue = queue.Queue()

# thread 1
def speechRecognition():
  while True:
    # wait for input like you were doing before
    # write to file as before
    # put message on the queue for other thread to get
    messageQueue.put(START_SPEAK_BACK)
    # Calling `get` with no arguments makes the call be
    # "blocking" in the sense that it won't return until
    # there is an element on the queue to get.
    messageFromOtherThread = messageQueue.get()
    # logically, messageFromOtherThread can only ever be
    # START_SPEECH_RECOGNITION, but you could still
    # check that this is true and raise an exception if not.

# thread 2
def speakBack():
  while True:
    messageFromOtherThread = messageQueue.get()
    # likewise, this message will only be START_SPEAK_BACK
    # but you could still check.
    # Here, fill in the code that speaks through the speakers.
    # When that's done:
    messageQueue.put(START_SPEECH_RECOGNITION)

一些评论:

  1. 此解决方案使用单个队列。它本来可以轻松地使用两个队列,一个用于speakBack->语音识别通信,另一个用于speechRecognition->通信。如果两个线程同时生成消息,则可能更有意义。

  2. 此解决方案实际上并不涉及检查邮件的内容。但是,如果需要在线程之间传递其他信息,则可以非常轻松地将对象或数据作为消息传递(而不仅仅是常量值)

  3. 最后,我不清楚为什么您不只是在同一线程中运行所有代码。您似乎希望程序执行一系列非常清晰的(串行)步骤:获取音频输入,将其写入文件,将其说出来,重新开始。将所有内容编写为普通的,串行的,无线程的python程序可能更有意义。