Search code examples
pythonmultithreadingfunctionvariables

Sharing variables between threads


I am using Vosk to make an audio player. I have created two functions: One to play the music and one to listen out for the user saying anything.

stop = False

def playMusic(stop): #This one plays the music while 'stop' is false
    while stop == False:
        music.play()
        time.sleep(music.get_length())
        break
    return
def checkwhileplaying(): #This one checks for any new messages from the user
    data = q.get()
    if rec.AcceptWaveform(data):
        time.sleep(1)
        if rec.Result()[2] == 't': #This puts the output as one simple sentence instead of 
            stopmessage = rec.Result()[14:-3]
        else:
            stopmessage = rec.Result()[17:-3]
    else:
        if rec.PartialResult()[2] == 't':
            time.sleep(1)
            stopmessage = rec.PartialResult()[14:-3]
        else:
            stopmessage = rec.PartialResult()[17:-3]
    if 'stop' in stopmessage:
        global stop
        stop = True
    
play = threading.Thread(target=playMusic,args=(stop,), daemon=True)
check = threading.Thread(target=checkwhileplaying, daemon=True)
play.start()
check.start()

The idea is that if the user wants to stop the music, they can say so. When the software detects the message, if the parameters are right, 'stop' will be set to true and the 'play' thread will stop playing the music.

However, when the code is run, it hears 'stop' but the thread playing the music doesn't stop. It doesn't detect the variable change.

I know it's something to do with the variable types (global, local, etc) but I can't seem to wrap my head around it. Can anyone help?

Any help is appreciated :)


Solution

  • it seems to me that the way you implement the playMusic function guarantees that it will always play until the end. You check the stop flag once, start playing the music, sleep until the music is over, break the cycle and return, so the stop flag is never checked again by that function.

    Consider playing the music first and then start a cycle that runs while stop is False. When the cycle breaks you can stop the music and return return.

    def playMusic(stop):
        music.play()
        while not stop:
            time.sleep(0.1)
        # music.stop()
        return