Qrashi
Qrashi

Reputation: 71

How to end a while loop in another Thread?

I would like to end a while True loop in another thread in python:

from time import sleep
from threading import Thread

condition = False

def check_sth():
    while True:
        if condition:
            print("Condition met, ending")
            break
        else:
            sleep(0.25)
            do_sth()  # Do something everytime the condition is not met

Thread(target=check_sth(), args=(,)).start()
sleep(2)
condition = False
#  Doesn't print "Condition met..."

Or is there a way to simply kill the created thread, so I can do the following:

thread = Thread(target=check_sth(), args=(,))
thread.start()
thread.kill() # (?)

Ways to do this using asyncio or another framework are also welcome.

Upvotes: 2

Views: 5889

Answers (4)

martineau
martineau

Reputation: 123463

Note your code isn't passing the arguments properly when creating the Thread, and never set the condition boolean variable to True.

Here's how to fix those things and be able to stop the while loop in the other thread. Instead of a simple boolean variable, it uses an Threading.Event object to control the loop and allow it to be set true from the main thread in a thread-safe way.

Code

from time import sleep
from threading import Event, Thread

condition = Event()

def do_sth():
    print("truckin' ...")

def check_sth():
    while not condition.is_set():
        sleep(0.25)
        do_sth()  # Do something everytime the condition is not set.

    print("Condition met, ending.")


Thread(target=check_sth, args=()).start()
sleep(2)
condition.set()  # End while loop.

Output

truckin' ...
truckin' ...
truckin' ...
truckin' ...
truckin' ...
truckin' ...
truckin' ...
truckin' ...
Condition met, ending.

Upvotes: 4

Solomon Slow
Solomon Slow

Reputation: 27115

is there a way to simply kill the...thread...?

It is practically never a smart idea to let one thread kill another. The reason is simple: Threads communicate with each other by altering the state of shared program variables. If thread A simply kills thread B without any form of synchronization between them, then there is no way for thread A to know, when is a safe time to kill thread B such that thread B will not leave things in an inconsistent/invalid state.

But, on the other hand, if you synchronize them, then you've made it possible for thread A to ask thread B to clean up and terminate itself.

Threads within the same program should always cooperate with each other.

Upvotes: 1

koringakek5
koringakek5

Reputation: 21

You are calling and passing the result of your check_sth function as the target argument to Thread. This is why your code doesn't work. This is what you should do instead:

from time import sleep
from threading import Thread

condition = False

def check_sth():
    while True:
        if condition:
            print("Condition met, ending")
            break
        else:
            sleep(0.25)
            do_sth()  # Do something everytime the condition is not met

Thread(target=check_sth).start()
sleep(2)
condition = True

Note I replaced check_sth() with check_sth. This way I'm passing the actual function, and not its result.

Upvotes: 0

balderman
balderman

Reputation: 23815

Create a Queue from Queue import Queue and pass it to the thread func. Inside the while loop read from the queue (using get). The main body of the code should put something in the queue that will flag the thread to stop.

Read more here.

Upvotes: 1

Related Questions