所以,我是线程的初学者。另一方面,这个程序有点庞大,但我会尽力只放必要的东西。
总而言之,我在线程中有一个队列,用于播放附加到队列中的音频文件,然后是一个初始 input(),之后是一个 while 循环,在其中我附加第一个条目,接下来我有一个 input()。
我的问题是线程在 input() 行代码的循环中冻结,但只是第一次。当我在 while 之外输入 input() 中的第一个条目时,该条目在 while 内成功排队(在播放音频文件之前)。但是,当循环到达 input() 行时,尝试播放音频文件的线程就会冻结,直到我键入第二个条目。然后,音频文件按原样播放,第二个条目也排队并播放(同时循环继续下一个 input())。从这里开始,循环和线程将按其应有的方式工作。让我无需等待正在播放的音频文件以及正在后台播放的音频文件即可输入条目。
顺便提一下,我不认为它只会冻结队列线程,但我认为整个代码都会冻结,直到键入第二个条目。
换句话说,代码在 input() 的第一个循环中冻结,并等待输入继续。但是,其余循环按其应有的方式工作,队列在后台接收条目并播放文件,而主代码只要求输入。
这些不是确切的功能,但具有相同的本质(我也测试了它们,它们有相同的错误):
主.py
play_queue = []
def read_queue():
while True:
if len(play_queue) != 0: # Whether is something in the queue
print("Getting file...")
file = play_queue[0]
print("Calling play function...")
play(file, SPEAKERS_ID)
print("Removing from queue...")
play_queue.pop(0) # Removes the audio from the queue
else: # Whether the queue is empty
sleep(0.5)
print("Empty queue")
def play(filename, device_id):
print("Starting play function...")
try:
print("Reading file") # This is the last print before the Thread (or the code) freezes and the only way to make it continue is typing another input (just the first time)
data, fs = sf.read(filename, dtype='float32') # Gets the audio file info.
print("File read")
print("Playing audio...")
sd.play(data, fs, device=device_id) # Plays the audio file
sd.wait()
print("Fin del audio.")
except Exception as e:
print(f"Un error desconocido ha ocurrido: {e}")
if __name__ == '__main__':
threading.Thread(target=read_queue, daemon=True).start() # This is the thread that reads the queue
song = input("Prompt: ") # Asks for the first input
while song.lower() != 'exit':
read_queue.append(song)
song = input("Prompt: ") # Second and subsequent inputs (freezes here the first time)
这是我第一个使用线程的项目,也是我第一次使用堆栈溢出 LUL。我将非常感谢任何可以帮助我的人。
一些注意事项:
我尝试过的事情: 我尝试进行大量 print() 来找出问题所在。我尝试在线程上执行 play() 函数,但这会破坏 while 循环,因此我必须进行大量更改才能工作(而且也没有解决问题)。我尝试询问 ChatGPT 哈哈哈(没有成功)。尝试更改第一个 input() 的位置(我不知道为什么,我想我只是在尝试一切)。我尝试不断打印队列内容,这仅确认音频已附加到队列中,但由于某种原因,线程冻结在 play() 函数的一半处。稍后也尝试放松并找到解决方案(是的,根本不起作用LMAO)。
变更日志: 编辑了整个帖子和代码。显然,库之间存在一些不兼容的问题(?在将另一个库导入到代码中后自行修复(是的,只是听起来如何……或读起来如何?lmao)。完整的代码很大,没有上限。但即使是第一个我发布的代码很大,所以我只是将其删除并发布了一个具有完全相同错误的较小示例。我希望这个更小且更简洁的版本可以帮助遇到相同错误的人。目前,我只能说导入图书馆我把答案放在下面。
好吧,所以...出于某种原因导入 lingua 库修复了它(? (是的,我也很困惑)。 显然这是 input() 的问题,我认为是包之间的不兼容。所以导入 lingua 库只是解决了不兼容性(?也许。
如果其他人使用线程、input() 和 while 循环遇到同样的问题,请发布。希望能解决问题。
顺便说一句,是的,它实际上是在导入库。如果我删除
from lingua import Language, LanguageDetectorBuilder
行,则错误就在那里。如果我添加它,错误就会消失。