Last Updated on September 12, 2022
You can kill a child process using the Process.kill() or Process.terminate() methods.
In this tutorial you will discover how to forcefully terminate or kill a process in Python.
Let’s get started.
Need to Kill a Process
A process is a running instance of a computer program.
Every Python program is executed in a Process, which is a new instance of the Python interpreter. This process has the name MainProcess and has one thread used to execute the program instructions called the MainThread. Both processes and threads are created and managed by the underlying operating system.
Sometimes we may need to create new child processes in our program in order to execute code concurrently.
Python provides the ability to create and manage new processes via the multiprocessing.Process class.
You can learn more about multiprocessing in the tutorial:
In concurrent programming, we sometimes may need to forcefully kill a child process.
This may be for many reasons, such as:
- The child process is out of control.
- The conditions required by the child process have changed.
- The program needs to be stopped immediately.
How can we forcefully terminate or kill a child process in Python?
Run loops using all CPUs, download your FREE book to learn how.
How to Kill a Process
Killing a process is drastic.
If possible, it is better to safely stop a child process.
This can be achieved in many ways. A common and reliable approach is to use a shared multiprocessing.Event object. The child process can check the status of the event frequently, and if set, it can clean-up resources and choose to stop.
You can learn more about safely stopping a child process in the tutorial:
Nevertheless, a process can be forcefully stopped immediately.
The downside is that the process will not have an opportunity to clean-up, making it possibly unsafe.
Specifically:
- The finally clauses in try-except-finally or try-finally patterns will not be executed.
- The exit handlers will not be executed.
This means that open resources like files and sockets will not be closed in a safe and controlled manner. It also means that any application state will not be updated.
Nevertheless, sometimes we may need to immediately kill a child process.
There are two main approaches to kill a process, they are:
- Terminate a process via Process.terminate().
- Kill a process via Process.kill().
Let’s take a closer look at each in turn.
Call terminate() on Process
A process can be killed by calling the Process.terminate() function.
The call will only terminate the target process, not child processes.
The method is called on the multiprocessing.Process instance for the process that you wish to terminate. You may have this instance from creating the process or it may be acquired via module methods such as the multiprocessing.active_children() function.
For example:
1 2 3 |
... # terminate the process process.terminate() |
The method takes no arguments and does not block.
The function will terminate the process using the SIGTERM (signal terminate) signal on most platforms, or the equivalent on windows.
The SIGTERM signal is sent to a process to request its termination. Unlike the SIGKILL signal, it can be caught and interpreted or ignored by the process. This allows the process to perform nice termination releasing resources and saving state if appropriate. SIGINT is nearly identical to SIGTERM.
— SIGTERM, Wikipedia.
Call kill() on Process
A process can be killed by calling the Process.kill() function.
The call will only terminate the target process, not child processes.
The method is called on the multiprocessing.Process instance for the process that you wish to terminate. You may have this instance from creating the process or it may be acquired via module methods such as the multiprocessing.active_children() function.
For example:
1 2 3 |
... # kill the process process.kill() |
The method takes no arguments and does not block.
The function will terminate the process using the SIGKILL (signal kill) signal on most platforms, or the equivalent on windows. This signal cannot be ignored and cannot be handled.
The SIGKILL signal is sent to a process to cause it to terminate immediately (kill). In contrast to SIGTERM and SIGINT, this signal cannot be caught or ignored, and the receiving process cannot perform any clean-up upon receiving this signal.
— SIGKILL, Wikipedia.
Now that we know how to kill a process let’s look at some worked examples.
Example of Terminating a Process
We can explore how to terminate a process.
In this example we will create a child process that will run a task in a loop forever. The parent process will wait a while then choose to forcefully terminate the process.
First, let’s define a task function that we can execute in a child process.
The function will use a while-loop and will loop forever. Each iteration, it will block for one second with a call to time.sleep() then report a message.
The task() function below implements this.
1 2 3 4 5 6 7 8 |
# custom task function def task(): # execute a task in a loop while True: # block for a moment sleep(1) # report a message print('Worker process running...', flush=True) |
Next, in the parent process we can create a new multiprocessing.Process instance to run our task() function in a new child process.
This can be achieved using the “target” keyword of the multiprocessing.Process class constructor.
1 2 3 |
... # create a process process = Process(target=task) |
Once created, we can start the process.
1 2 3 |
... # run the process process.start() |
The parent process can then block for five seconds with a call to time.sleep().
1 2 3 |
... # wait for a moment sleep(5) |
The parent process will then wake up and forcefully terminate the child process.
1 2 3 |
... # terminate the process process.terminate() |
The main process will then carry on, in this case reporting a message.
1 2 3 |
... # continue on... print('Parent is continuing on...') |
Tying this together, the complete example is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# SuperFastPython.com # example of terminating a process from time import sleep from multiprocessing import Process # custom task function def task(): # execute a task in a loop while True: # block for a moment sleep(1) # report a message print('Worker process running...', flush=True) # entry point if __name__ == '__main__': # create a process process = Process(target=task) # run the process process.start() # wait for a moment sleep(5) # terminate the process process.terminate() # continue on... print('Parent is continuing on...') |
Running the example first creates and starts a new child process to run our target function.
The child process is started and the parent process blocks.
The child process attempts to run forever, reporting a message and sleeping for a second each iteration.
The parent process wakes up then forcefully terminates the child process.
The child process is stopped immediately. The parent process then carries on and then decides to stop.
1 2 3 4 5 |
Worker process running... Worker process running... Worker process running... Worker process running... Parent is continuing on... |
Next, let’s look at killing a process.
Free Python Multiprocessing Course
Download your FREE multiprocessing PDF cheat sheet and get BONUS access to my free 7-day crash course on the multiprocessing API.
Discover how to use the Python multiprocessing module including how to create and start child processes and how to use a mutex locks and semaphores.
Example of Killing a Process
We can explore how to kill a process.
In this example we will create a child process that will run a task in a loop forever, as in the previous section. The parent process will wait a while then choose to kill the child process.
First, let’s define a task function that we can execute in a child process.
The function will use a while-loop and will loop forever. Each iteration, it will block for one second with a call to time.sleep() then report a message.
The task() function below implements this.
1 2 3 4 5 6 7 8 |
# custom task function def task(): # execute a task in a loop while True: # block for a moment sleep(1) # report a message print('Worker process running...', flush=True) |
Next, in the parent process we can create a new multiprocessing.Process instance to run our task() function in a new child process.
This can be achieved using the “target” keyword of the multiprocessing.Process class constructor.
1 2 3 |
... # create a process process = Process(target=task) |
Once created, we can start the process.
1 2 3 |
... # run the process process.start() |
The parent process can then block for five seconds with a call to time.sleep().
1 2 3 |
... # wait for a moment sleep(5) |
The parent process will then wake up and kill the child process.
1 2 3 |
... # kill the process process.kill() |
The main process will then carry on, in this case reporting a message.
1 2 3 |
... # continue on... print('Parent is continuing on...') |
Tying this together, the complete example is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# SuperFastPython.com # example of killing a process from time import sleep from multiprocessing import Process # custom task function def task(): # execute a task in a loop while True: # block for a moment sleep(1) # report a message print('Worker process running...', flush=True) # entry point if __name__ == '__main__': # create a process process = Process(target=task) # run the process process.start() # wait for a moment sleep(5) # kill the process process.kill() # continue on... print('Parent is continuing on...') |
Running the example first creates and starts a new child process to run our target function.
The child process is started and the parent process blocks.
The child process attempts to run forever, reporting a message and sleeping for a second each iteration.
The parent process wakes up then kills the child process.
The child process is stopped immediately. The parent process then carries on and then decides to stop.
1 2 3 4 5 |
Worker process running... Worker process running... Worker process running... Worker process running... Parent is continuing on... |
Overwhelmed by the python concurrency APIs?
Find relief, download my FREE Python Concurrency Mind Maps
Common Questions
This section lists common questions about killing a process.
Do you have a question?
Let me know in the comments below and I may add it to this section.
When to Use terminate() vs kill()?
Generally, a SIGTERM sent via terminate() is less forceful than SIGKILL sent via kill().
This is because a SIGTERM can be handled with a signal handler, whereas a SIGKILL cannot.
Nevertheless, for most purposes, the two approaches are equivalent.
Can the SIGTERM Triggered via Process.terminate() Be Handled?
Yes.
You can register a function to handle the signal via the signal.signal() function.
The example below demonstrates how to register a handler for SIGTERM in the child process, allowing it to clean-up before exiting.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# SuperFastPython.com # example of terminating a child process, and handling the signal from time import sleep from multiprocessing import Process from signal import signal from signal import SIGTERM import sys # handle signal def handler(sig, frame): print('Child process cleaning up...') sleep(2) # kill the process sys.exit(0) # custom task function def task(): # handle sigterm signal(SIGTERM, handler) # execute a task in a loop while True: # block for a moment sleep(1) # report a message print('Worker process running...', flush=True) # entry point if __name__ == '__main__': # create a process process = Process(target=task) # run the process process.start() # wait for a moment sleep(5) # terminate the process process.terminate() # continue on... print('Parent is continuing on...') |
Can the SIGKILL Triggered via Process.kill() Be Handled?
No.
What Happens to Child Processes?
A process with child processes may be killed.
In this case, the target process is killed and the child processes are left untouched. As they no longer have a parent process, they are referred to as orphan processes.
Further Reading
This section provides additional resources that you may find helpful.
Python Multiprocessing Books
- Python Multiprocessing Jump-Start, Jason Brownlee (my book!)
- Multiprocessing API Interview Questions
- Multiprocessing API Cheat Sheet
I would also recommend specific chapters in the books:
- Effective Python, Brett Slatkin, 2019.
- See: Chapter 7: Concurrency and Parallelism
- High Performance Python, Ian Ozsvald and Micha Gorelick, 2020.
- See: Chapter 9: The multiprocessing Module
- Python in a Nutshell, Alex Martelli, et al., 2017.
- See: Chapter: 14: Threads and Processes
Guides
- Python Multiprocessing: The Complete Guide
- Python Multiprocessing Pool: The Complete Guide
- Python ProcessPoolExecutor: The Complete Guide
APIs
References
Takeaways
You now know how to forcefully kill a process in Python.
Do you have any questions?
Ask your questions in the comments below and I will do my best to answer.
Photo by Rusty Watson on Unsplash
Do you have any questions?