Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python subprocess timeout: kill and reap the timed-out child

Last updated: 1 Oct 20265 min read
tutorial
IntermediateBy AITrove Editorial

A Popen timeout raises without stopping the child; the owner must terminate and collect it.

Download Python source kit

Operation contract

A receipt import starts a separate interpreter. communicate(timeout=...) limits this one wait, and TimeoutExpired leaves the process alive. The exception path kills it, then calls communicate again to close the pipes and collect its return status. A subprocess that launches its own descendants needs a separately designed process-group policy; killing one PID does not imply a whole tree stopped.

Failure and ownership boundary

The fixture uses a sleeping child so the timeout is reproducible. A launch failure occurs before Popen returns and belongs to a different error path. communicate buffers pipe output in memory: use an output budget or a file for untrusted volume. An OS process supervisor may also need to own shutdown when the parent dies.

Working program

python
import subprocess
import sys

child = subprocess.Popen(
    [sys.executable, "-c", "import time; time.sleep(1)"],
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
)
try:
    child.communicate(timeout=0.02)
    timed_out = False
except subprocess.TimeoutExpired:
    timed_out = True
    child.kill()
    child.communicate()
print("timed_out", timed_out)
print("reaped", child.returncode is not None)

Output

Output
timed_out True
reaped True

Costs and limits

Process creation and shutdown dominate this tiny fixture. The wait is bounded, but the second communicate can still retain output; set output limits for an untrusted child.

Common Mistakes

  • A timeout exception does not kill the process.
  • Calling wait with unread pipes can deadlock when the child fills them.
  • Killing the direct child is not a process-tree policy.

Connected lessons

Test this boundary.

Continue with Python POSIX subprocess timeout: stop the owned process group.

python
subprocess-timeout-reap
Storage details