Kill Process By PID in Python

June 14, 2022 Python Multiprocessing

You can kill a process via its process identifier, pid, via the os.kill() function.

In this tutorial you will discover how to kill a process via its pid.

Let's get started.

Need To Kill a Process by PID

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 multiprocessing, we may need to kill a process by its process identifier or PID.

This may be for many reasons, such as:

How can we kill a process via its pid in Python?

How To Kill a Process via its PID

You can kill a process via its pid with the os.kill() function.

The os.kill function takes two arguments, the process identifier (pid) to kill, and the signal to send to kill the process.

The signal is a constant from the signal module, such as signal.SIGINT or signal.SIGKILL.

For example:

...
# kill a process via pid
os.kill(12345, signal.SIGKILL)

We need to know the pid for the process that is to be killed.

This can be retrieved from the multiprocessing.Process instance for the process via the pid attribute.

For example:

...
# get the pid
pid = process.pid

The multiprocessing.Process instance may be managed by the parent process when the child process is created, or accessed via a module function such as multiprocessing.active_children() or multiprocessing.parent_process().

You can learn more about getting the process pid in the tutorial:

The SIGINT or signal interrupt can be used to terminate the target process, which is equivalent to the user pressing CONTROL-C on the process. Alternately, the SIGKILL or signal kill process can be used to terminate the process forcefully.

The difference between SIGINT and SIGKILL is that it is possible for a process to detect and handle a SIGINT, whereas a SIGKILL cannot be handled.

Now that we know how to kill a process via pid, let's look at some worked examples.

Kill Current Process via PID

It is possible to kill the current process via pid.

This can be achieved by first getting the pid for the current process, then calling os.kill() with the pid and the signal to kill the process, such as SIGKILL.

First, we can get the pid for the current process using the os.getpid(), and report the result.

...
# get the pid of the current process
pid = getpid()
# report a message
print(f'Running with pid: {pid}')

Next, we can kill the process using the signal.SIGKILL signal.

...
# attempt to kill the current process
kill(pid, SIGKILL)

Tying this together, the complete example is listed below.

# SuperFastPython.com
# example of killing the current process via pid
from os import kill
from os import getpid
from signal import SIGKILL
# get the pid of the current process
pid = getpid()
# report a message
print(f'Running with pid: {pid}')
# attempt to kill the current process
kill(pid, SIGKILL)
# report a message
print('Skill running')

Running the example first gets the pid for the current process, then reports the value.

Note, the pid for the process will differ each time the program is run.

Next, the current process is killed via its pid, e.g, the process kills itself.

Running with pid: 21390

Next, let's look at how we might kill a child process.

Kill Child Process via PID

We can kill a child process via its pid.

In this example, we will first start a child process that will block for an extended period to keep it occupied. The parent process will then access the pid for the child process and terminate it via the SIGKILL.

First, we can define a function used to run in the new child process.

The task() function below implements this, reporting a message and sleeping for ten seconds.

# function executed in a child process
def task():
    # report a message
    print('Child is running...', flush=True)
    # block for a while
    sleep(10)

Next, the main process will create and configure a new multiprocessing.Process instance to run the function in a new child process. Then the child process is started.

...
# start a child process
child = Process(target=task)
child.start()

The parent process then blocks a moment to allow the child process to start, then reports the pid for the child process via the multiprocessing.Process.pid attribute.

...
# wait a moment
sleep(1)
# report a message
print(f'Child is running with pid: {child.pid}')

Next, the child process is killed via its process id and the SIGKILL signal.

...
# attempt to kill the child process
kill(child.pid, SIGKILL)

The parent process then blocks until the child process is completely stopped and then reports the status of the child process.

...
# wait for child to terminate
child.join()
# report status of the child
print(f'Child process: {child}')

Tying this together, the complete example is listed below.

# SuperFastPython.com
# example of killing a child process by pid
from time import sleep
from multiprocessing import Process
from os import kill
from os import getpid
from signal import SIGKILL

# function executed in a child process
def task():
    # report a message
    print('Child is running...', flush=True)
    # block for a while
    sleep(10)

# protect the entry point
if __name__ == '__main__':
    # start a child process
    child = Process(target=task)
    child.start()
    # wait a moment
    sleep(1)
    # report a message
    print(f'Child is running with pid: {child.pid}')
    # attempt to kill the child process
    kill(child.pid, SIGKILL)
    # wait for child to terminate
    child.join()
    # report status of the child
    print(f'Child process: {child}')

Running the example first configures and starts the child process.

The child process starts, reports a message, then blocks for ten seconds.

The parent process blocks for one second, to allow the child process to start up completely.

The parent process then reports the pid of the child process and kills it via the pid.

The parent process waits for the child process to shutdown completely, then reports the status of the child process.

We can see that the child process is not marked as "stopped" and that its exit code was the negative value of the signal used to terminate it, e.g. -SIGKILL.

Child is running...
Child is running with pid: 21398
Child process: <Process name='Process-1' pid=21398 parent=21396 stopped exitcode=-SIGKILL>

Next, let's look at how we might kill the parent process via pid.

Kill Parent Process via PID

We can kill the parent process via pid.

In this example we can create a child process that will get the pid for the parent process, then kill the parent process via its pid.

First, we can define a function to run in a child process.

# function executed in a child process
def task():
	# ...

First, the child process will block for a second.

...
# wait a moment
sleep(1)

Next, it will get a multiprocessing.Process instance for the parent process via the multiprocessing.parent_process() module function.

...
# get the parent process
parent = parent_process()

Next, the pid of the parent process is reported.

...
# report a message
print(f'Parent is running with pid: {parent.pid}', flush=True)

The parent process can then be killed via its pid.

...
# attempt to kill the parent process
kill(parent.pid, SIGKILL)

The child process then blocks until the parent process has stopped completely, then reports the details of the parent process.

...
# wait for parent to terminate
parent.join()
# report status of the parent
print(f'Parent process: {parent}', flush=True)

Tying this together, the complete task() function is listed below.

# function executed in a child process
def task():
    # wait a moment
    sleep(1)
    # get the parent process
    parent = parent_process()
    # report a message
    print(f'Parent is running with pid: {parent.pid}', flush=True)
    # attempt to kill the parent process
    kill(parent.pid, SIGKILL)
    # wait for parent to terminate
    parent.join()
    # report status of the parent
    print(f'Parent process: {parent}', flush=True)

Next, the main process, the child process is configured and started.

...
# start a child process
child = Process(target=task)
child.start()

The parent process then blocks for ten seconds, waiting to be killed.

...
# wait for a while
sleep(10)
# report a message
print('Parent is still running')

Tying this together, the complete example is listed below.

# SuperFastPython.com
# example of killing a parent process by pid
from time import sleep
from multiprocessing import parent_process
from multiprocessing import Process
from os import kill
from signal import SIGKILL

# function executed in a child process
def task():
    # wait a moment
    sleep(1)
    # get the parent process
    parent = parent_process()
    # report a message
    print(f'Parent is running with pid: {parent.pid}', flush=True)
    # attempt to kill the parent process
    kill(parent.pid, SIGKILL)
    # wait for parent to terminate
    parent.join()
    # report status of the parent
    print(f'Parent process: {parent}', flush=True)

# protect the entry point
if __name__ == '__main__':
    # start a child process
    child = Process(target=task)
    child.start()
    # wait for a while
    sleep(10)
    # report a message
    print('Parent is still running')

Running the example first configures and starts a child process.

The parent process then blocks for ten seconds.

The child process blocks for a second, then gets the parent process and reports its pid.

The child process then kills the parent process via its pid.

Next, the child process blocks until the parent process terminates completely, then reports the details of the parent process.

We can see the details of the parent process, which is the main process.

Parent is running with pid: 21421
Parent process: <_ParentProcess name='MainProcess' parent=None unknown>

Takeaways

You now know how to kill a process via its pid.



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.