Skip to content

Thread.join() cannot be interrupted by Ctrl+C on Windows #139689

@james-oldfield-inex

Description

@james-oldfield-inex

Bug report

Bug description:

The following short program will always run for 10 seconds on Windows, no matter how quickly you press ctrl+C.

from threading import Thread
import time

t = Thread(target=time.sleep, args=(10,))
t.start()

try:
    print("Joining ...")
    t.join()
    print("Joined without exception")
except KeyboardInterrupt:
    print("Keyboard interrupt")

The program does print "Keyboard interrupt", so the signal handler does actually get run and the exception gets thrown. It just doesn't interrupt the join. Indeed, if the thread function is changed to one that runs forever then this code would wait forever too.

The following expanded version, with a custom signal handler, shows that the signal handler is not run until the join() completes. (As opposed to the possibility that it runs straight away, but then the join() wait resumes before raising the exception. Unlikely I know.)

Version with custom signal handler
import signal
from threading import Thread
import time

start_time = time.monotonic()
def pr(s):
    print(f"{time.monotonic() - start_time:.2f} {s}")

def sig_handler(signal, frame):
    pr("Ctrl-C")
    raise KeyboardInterrupt

signal.signal(signal.SIGINT, sig_handler)

t = Thread(target=time.sleep, args=(10,))
t.start()

try:
    pr("Joining ...")
    t.join()
    pr("Joined without exception")
except KeyboardInterrupt:
    pr("Keyboard interrupt")

If ctrl+c is pressed within 10 seconds then this prints:

0.00 Joining ...
10.00 Ctrl-C
10.00 Keyboard interrupt

Related issues:

One of the comments on #66021 is about this Thread.join() rather than the real topic of that issue, but they are told "This is a different issue: bpo-29971. Currently, threading.Lock.acquire() cannot be interrupted by CTRL+C." This suggests to me that #74157 is very related to Thread.join() not being interruptable. But it's not exactly the same ... because it's marked as fixed and this issue still persists.

CPython versions tested on:

3.10, 3.12

Operating systems tested on:

Windows

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions