- How to Stop a Thread in Python
- Need to Stop a Thread
- How to Stop a Thread
- Example of Stopping a Thread With a Custom Function
- Custom Function in a New Thread
- Stop Custom Function in New Thread
- Example of Stopping a Thread With an Extended Class
- Custom Thread Class
- Stop Custom Thread Class
- Common Questions About Stopping Threads
- What if My Task Does Not Have a Loop?
- What if My Task Raises An Exception?
- What if My New Thread Has Already Stopped?
- What if My New Thread is a Daemon Thread?
- How Can We Stop Multiple Threads?
- How Can We Stop Daemon Threads?
- How Can We Stop Tasks in a ThreadPoolExecutor?
- Further Reading
- Takeaways
How to Stop a Thread in Python
You can stop a thread by using a threading.Event.
In this tutorial you will discover how to gracefully stop a thread in Python.
Need to Stop a Thread
A thread is a thread of execution in a computer program.
Every Python program has at least one thread of execution called the main thread. Both processes and threads are created and managed by the underlying operating system.
Sometimes we may need to create additional threads in our program in order to execute code concurrently.
Python provides the ability to create and manage new threads via the threading module and the threading.Thread class.
You can learn more about Python threads in the guide:
In concurrent programming, we may run a task in a new thread, then later decide to stop the task.
This may be for many reasons, such as:
- The result from the task is no longer required.
- The application is shutting down.
- The outcome from the task has gone astray.
Python provides no way to stop a running thread in the API.
How can we stop a thread in Python?
Run your loops using all CPUs, download my FREE book to learn how.
How to Stop a Thread
A thread can be stopped using a shared boolean variable such as a threading.Event.
A threading.Event is a thread-safe boolean variable flag that can be either set or not set. It can be shared between threads and checked and set without fear of a race condition.
If you are new to threading.Events, you can learn more here:
A new event can be created and then shared between threads, for example:
The event is created in the ‘not set‘ or False state.
We may have a task in a custom function that is run in a new thread. The task may iterate, such as in a while-loop or a for-loop.
We can update our task function to check the status of an event each iteration.
If the event is set true, we can exit the task loop or return from the task() function, allowing the new thread to terminate.
The status of the threading.Event can be checked via the is_set() function.
The main thread, or another thread, can then set the event in order to stop the new thread from running.
The event can be set or made True via the set() function.
Now that we know how to stop a Python thread, let’s look at some worked examples.
Confused by the threading module API?
Download my FREE PDF cheat sheet
Example of Stopping a Thread With a Custom Function
In this section we can explore how to stop a thread that is executing a custom function.
First, we will develop an example that runs a custom function in a separate thread, then we will look at how to update the example to stop the thread on demand.
Custom Function in a New Thread
We can develop an example that runs a function in a new thread.
The new task function will execute in a loop and once finished the new thread will terminate and the main thread will terminate.
Firstly, we can define the task function.
The function will execute a loop five times. Each iteration it will block for a second, then report a message in an effort to simulate work and show progress.
Once the task is finished, the function will report a final message.
The task() function below implements this.
Next, in the main thread we can create a new threading.Thread instance that is configured to execute our task() function in a new thread via the “target” argument.
We can then immediately start the new thread via the start() function.
The main thread will then wait for the new thread to finish by joining the thread.
If you are new to joining threads, you can learn more here:
Tying this together, the complete example is listed below.
Running the example first creates and starts the new thread.
The main thread then blocks until the new thread finishes.
The new thread executes in a loop, blocking for a moment and reporting progress. After five iterations of the loop, the new thread reports a final message and terminates.
The main thread notices that the new thread has finished and then terminates itself, closing the program.
Next, let’s look at how we might update this example to stop the thread on demand.
Stop Custom Function in New Thread
We can update the example from the previous section to stop the new thread on demand.
This can be achieved by creating a new threading.Event instance, passing it as an argument to the new thread, and then updating the custom function to check if the event is set each iteration. Once the event is set, the function can break its task loop and exit, terminating the new thread.
Firstly, we can update the task function to take the shared threading.Event instance as an argument.
We can then update the task loop to check the status of the event each iteration, and if set to break the task loop.
Tying this together, the updated task() function with these changes is listed below.
Next, in the main thread can first create a new threading.Event instance to be shared between the threads.
We can then update the main thread to block for a few seconds.
Finally, we can set the event and trigger the new thread to stop.
Tying this together, the complete example is listed below.
Running the example first creates and starts the new thread.
The main thread then blocks for a few seconds.
Meanwhile, the new thread executes its task loop, blocking and reporting a message each iteration. It checks the event each iteration, which remains false and does not trigger the thread to stop.
The main thread wakes up, and then sets the event. It then joins the new thread, waiting for it to terminate.
The task thread checks the event which is discovered to be set (e.g, True). The thread breaks the task loop, reports a final message then terminates the new thread.
The main thread then terminates, closing the Python process.
Now that we know how to stop a custom function running in a new thread, let’s look at an example of stopping a custom thread class.
Free Python Threading Course
Download my threading API cheat sheet and as a bonus you will get FREE access to my 7-day email course.
Discover how to use the Python threading module including how to create and start new threads and how to use a mutex locks and semaphores
Example of Stopping a Thread With an Extended Class
In this section we can explore how to stop a thread that is an object that extends the threading.Thread class.
First, we will develop an example that extends the threading.Thread class, then we will look at how to update the example to stop the thread on demand.
Custom Thread Class
We can run a task in a new thread by extending the threading.Thread class and overriding the constructor and the run() function.
In this section, we will show how to run the same task as in the previous section within a custom thread class.
Firstly, we can define a new class that extends threading.Thread.
The new class must implement a constructor and call the constructor of the threading.Thread class to properly initialize the underlying thread instance.
We can then override the run() method on the threading.Thread class.
This function will run in a new thread once the thread is started via the start() function. Specifically we call start() and start() will call run() for us in a new thread of execution.
Our task will be to execute a loop five times, block for a second to simulate work, and report a message. Then report a message once the task is complete.
Tying this together the new CustomThread class is listed below.
Next, in the main thread, we can create a new instance of our custom thread class and start it in order to execute our task in a new thread.
We will then join() the new thread and wait for the new thread to terminate, before terminating the main thread.
Tying this together, the complete example is listed below.
Running the example first creates our custom thread class then starts executing the new thread.
The main thread then blocks waiting for the new thread to finish.
Our custom thread class runs our task in a new thread of execution, looping five times. Each iteration it blocks for a moment then reports a message.
Once the task is finished, it reports a final message.
The new thread terminates, then the main thread terminates, closing the process.
Next, let’s look at how we might update this example to stop the task on demand.
Stop Custom Thread Class
We can update the example in the previous section to stop the thread on demand.
This can be achieved by sharing a threading.Event with the new thread and updating the run() function to check if the event is set each iteration. Once set, the run() function can exit, which will terminate the new thread.
Firstly, we can update the constructor of our new thread class to take the shared threading.Event as an argument and then store it as a member variable.
Next, we can update the run() function to check the status of the threading.Event each iteration and to break the task loop once the event is set.
Tying this together, the updated CustomThread class that can be stopped on demand is listed below.
In the main thread, we must first create an instance of an event that can be shared between threads.
We must then pass it to the constructor of our new CustomThread class.
We can then update the new thread to block for a few seconds, then request that the new thread terminate by setting the event.
Finally, the main thread will wait for the new thread to terminate.
Tying this together, the complete example is listed below.
Running the example first involves creating an instance of the custom thread and starting it.
The main thread will then block for a few seconds.
The new thread will start executing its task loop, blocking for a moment and reporting progress.
The main thread then wakes up and sets the event, triggering the new thread to stop.
The new thread notices that the event is set and then exits the task loop, reporting a final message and terminating the new thread.
The main thread waits for the new thread to terminate, before then stopping itself and closing the application.
Overwheled by the python concurrency APIs?
Find relief, download my FREE Python Concurrency Mind Maps
Common Questions About Stopping Threads
This section lists common questions about stopping a new thread in Python.
Do you have any questions about stopping a new thread? Let me know in the comments and I will do my best to help.
What if My Task Does Not Have a Loop?
Your task does not need to have a loop in order to be stopped.
Instead, you need to add frequent checks of the shared threading.Event and return from the task() function or run() function once the event is set.
This will depend on the specifics of the task you wish to exit in a new thread.
If your task involves blocking, such as reading or writing IO or waiting on another thread, you may want to adopt a busy wait and have the threading.Event checked each iteration.
You can learn more about implementing a busy wait here:
If your task remains idle for some time, such as waiting for sporadic events, it may be able to wait on the threading.Event itself via the wait() function.
What if My Task Raises An Exception?
If your task executing in a new thread raises an exception that is not handled, it will terminate the thread.
This could be an alternate way for you to trigger a new thread to terminate, if convenient.
What if My New Thread Has Already Stopped?
If the new thread has already stopped and you set the event, it will not have any effect.
It would not be a problem.
What if My New Thread is a Daemon Thread?
If your task is executing in a daemon thread, then there is no need to stop it manually as it will be terminated for you once all non-daemon threads (e.g. the main thread) terminate.
You can learn more about daemon threads here:
If you want to manually stop your daemon thread, you can use the same method as above.
You can see an example of this here:
How Can We Stop Multiple Threads?
You can share the same threading.Event between all of the threads that might want to stop.
Each thread can frequently check the status of the event.
Once set, all threads can exit their task and terminate.
How Can We Stop Daemon Threads?
The same technique of using a threading.Event can be used to stop daemon threads.
You can see an example of this here:
How Can We Stop Tasks in a ThreadPoolExecutor?
The same technique of using a threading.Event can be used to stop tasks executing in a ThreadPoolExecutor.
You can see an example of this here:
Further Reading
This section provides additional resources that you may find helpful.
I also recommend specific chapters in the following books:
- Python Cookbook, David Beazley and Brian Jones, 2013.
- See: Chapter 12: Concurrency
- See: Chapter 7: Concurrency and Parallelism
- See: Chapter: 14: Threads and Processes
Takeaways
You now know how to stop a thread in Python.
Do you have any questions?
Ask your questions in the comments below and I will do my best to answer.