While working in Python, there might be situations where you need to execute external programs or scripts during runtime. In such cases, you can use the subprocess
module, which allows you to trigger new processes.
In such situations, you may need to terminate or kill a subprocess due to various reasons, such as a subprocess being unresponsive or taking much time to get completed.
In this article, we will discuss various methods to kill a subprocess in Python with code examples.
What is a Subprocess in Python?
Before we delve into the methods of killing subprocesses, let’s briefly understand what a subprocess is in Python. A subprocess is an additional process that is created by a main process (your Python script) to execute a separate program or script.
The subprocess module provides a simple and consistent interface to create and interact with additional processes.
1) Terminating a subprocess using terminate()
method
The terminate()
method is a part of the Popen
class in the subprocess
module. It sends a SIGTERM
signal to the process, allowing the process to perform cleanup operations before terminating.
However, it does not guarantee that the process will be terminated, as it depends on how the process handles the SIGTERM
signal.
Example
Let’s see an example of how to use the terminate()
method:
import subprocess
import time
process = subprocess.Popen(['sleep', '10'])
time.sleep(2)
process.terminate()
process.wait()
In this example, we started a subprocess using the sleep
command, which causes the subprocess to wait for 10 seconds. After a 2-second sleep, we use the terminate()
method to send the SIGTERM
signal to the subprocess. Thereafter, we used process.wait()
to wait for the process to finish if its not finished.
2) Killing a subprocess using kill()
method
The kill()
method is also a part of the Popen
class in the subprocess
module. It sends a SIGKILL
signal to the process, forcefully terminating it without giving it a chance to perform any cleanup operations. This method guarantees that the process will be terminated.
Example
Here’s an example using the kill()
method:
import subprocess
import time
process = subprocess.Popen(['sleep', '10'])
time.sleep(2)
process.kill()
process.wait()
In this example, we again started a subprocess using the sleep
command, which causes the subprocess to wait for 10 seconds and after a 2-seconds sleep, we called the kill()
method to send the SIGKILL
signal to the subprocess, forcefully terminating it. Lastly, we use process.wait()
to wait for the process to finish, if it hasn’t already.
3) Using os.kill()
method
The os.kill()
method is part of the os
module and allows you to send signals to a process using its process ID (PID). This method can be used to send both SIGTERM
and SIGKILL
signals.
Example
Here’s an example using the os.kill()
method:
import subprocess
import os
import signal
import time
process = subprocess.Popen(['sleep', '10'])
time.sleep(2)
os.kill(process.pid, signal.SIGTERM)
process.wait()
4) Using signal
module
The signal
module provides mechanisms to use signals in Python. It can be used in conjunction with the os
module to send signals such as SIGTERM
and SIGKILL
to a process.
Example
Here’s an example using the signal
module:
import subprocess
import os
import signal
import time
process = subprocess.Popen(['sleep', '10'])
time.sleep(2)
os.kill(process.pid, signal.SIGKILL)
process.wait()
5) Handling subprocess timeouts
The subprocess
module provides a timeout
parameter for some of its functions, such as run()
, call()
, and check_output()
. If the timeout is reached, a TimeoutExpired
exception is raised.
Example
Here’s an example of handling a subprocess timeout:
import subprocess
try:
result = subprocess.run(['sleep', '10'], timeout=5)
except subprocess.TimeoutExpired:
print("Subprocess timed out.")
In this example, we start a subprocess using the sleep
command, which causes the subprocess to wait for 10 seconds. We set the timeout
parameter to 5 seconds. If the subprocess takes longer than 5 seconds to complete, a TimeoutExpired
exception is raised, and we print “Subprocess timed out.”
6) Gracefully stopping a subprocess
Gracefully stopping a subprocess involves giving the process an opportunity to perform cleanup operations before terminating. This can be achieved by sending a SIGTERM
signal, waiting for a specified period, and then sending a SIGKILL
signal if the process has not terminated.
Example
import subprocess
import os
import signal
import time
process= subprocess.Popen(['sleep', '10'])
time.sleep(2)
os.kill(process.pid, signal.SIGTERM)
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
os.kill(process.pid, signal.SIGKILL)
process.wait()
print("Subprocess terminated.")
Above we followed the same patter after that we wait for the process to finish with a timeout of 5 seconds. If the process does not terminate within the timeout, we send the SIGKILL
signal to forcefully terminate it. Finally, we print “Subprocess terminated.”
Conclusion
In this article, we have discussed different methods to kill a subprocess in Python, including the terminate()
and kill()
methods provided by the subprocess
module, the os.kill()
method, the signal
module, and handling subprocess timeouts. Each method has its use cases and trade-offs, so choose the one that best fits your needs.
Leave a Reply