Kill a Process in Python

May 22, 2022 Python Multiprocessing

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:

How can we forcefully terminate or kill a child process in Python?

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:

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:

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:

...
# 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:

...
# 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.

# 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.

...
# create a process
process = Process(target=task)

Once created, we can start the process.

...
# run the process
process.start()

The parent process can then block for five seconds with a call to time.sleep().

...
# wait for a moment
sleep(5)

The parent process will then wake up and forcefully terminate the child process.

...
# terminate the process
process.terminate()

The main process will then carry on, in this case reporting a message.

...
# continue on...
print('Parent is continuing on...')

Tying this together, the complete example is listed below.

# 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.

Worker process running...
Worker process running...
Worker process running...
Worker process running...
Parent is continuing on...

Next, let's look at killing a process.

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.

# 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.

...
# create a process
process = Process(target=task)

Once created, we can start the process.

...
# run the process
process.start()

The parent process can then block for five seconds with a call to time.sleep().

...
# wait for a moment
sleep(5)

The parent process will then wake up and kill the child process.

...
# kill the process
process.kill()

The main process will then carry on, in this case reporting a message.

...
# continue on...
print('Parent is continuing on...')

Tying this together, the complete example is listed below.

# 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.

Worker process running...
Worker process running...
Worker process running...
Worker process running...
Parent is continuing on...

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.

# 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.

Takeaways

You now know how to forcefully kill a process in Python.



If you enjoyed this tutorial, you will love my book: Python Multiprocessing Jump-Start. It covers everything you need to master the topic with hands-on examples and clear explanations.