Title: GitHub · Where software is built
Open Graph Title: python/cpython
X Title: python/cpython
Description: The Python programming language. Contribute to python/cpython development by creating an account on GitHub.
Open Graph Description: The Python programming language. Contribute to python/cpython development by creating an account on GitHub.
X Description: The Python programming language. Contribute to python/cpython development by creating an account on GitHub.
Opengraph URL: https://github.com/python/cpython
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Thread.join() cannot be interrupted by Ctrl+C on Windows","articleBody":"# Bug report\n\n### Bug description:\n\nThe following short program will always run for 10 seconds on Windows, no matter how quickly you press ctrl+C.\n\n```python\nfrom threading import Thread\nimport time\n\nt = Thread(target=time.sleep, args=(10,))\nt.start()\n\ntry:\n print(\"Joining ...\")\n t.join()\n print(\"Joined without exception\")\nexcept KeyboardInterrupt:\n print(\"Keyboard interrupt\")\n```\n\nThe 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.\n\nThe 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.)\n\n\u003cdetails\u003e\n\u003csummary\u003eVersion with custom signal handler\u003c/summary\u003e\n\n```python\nimport signal\nfrom threading import Thread\nimport time\n\nstart_time = time.monotonic()\ndef pr(s):\n print(f\"{time.monotonic() - start_time:.2f} {s}\")\n\ndef sig_handler(signal, frame):\n pr(\"Ctrl-C\")\n raise KeyboardInterrupt\n\nsignal.signal(signal.SIGINT, sig_handler)\n\nt = Thread(target=time.sleep, args=(10,))\nt.start()\n\ntry:\n pr(\"Joining ...\")\n t.join()\n pr(\"Joined without exception\")\nexcept KeyboardInterrupt:\n pr(\"Keyboard interrupt\")\n```\n\nIf ctrl+c is pressed within 10 seconds then this prints:\n```\n0.00 Joining ...\n10.00 Ctrl-C\n10.00 Keyboard interrupt\n```\n\u003c/details\u003e\n\n**Related issues:**\n\n* #66021 ([bpo-21822](https://bugs.python.org/issue21822)) Sounds similar but is about `Thread.join()` not returning even after the thread is actually finished. In contrast, this issue is about wanting `Thread.join()` to complete *before* the thread is finished.\n* #89437 ([bpo-45274](https://bugs.python.org/issue45274)) This is about the same thing; the above issue was marked as a duplicate of this one.\n* #74157 ([bpo-29971](https://bugs.python.org/issue29971)) This looks like it's a similar bug but for a different call (`Lock.acquire()` rather than `Thread.join()`.\n* #89464 ([bpo-45301](https://bugs.python.org/issue45301) This is referenced from the above issues, but I'm not sure of the exact relationship.\n\n[One of the comments](https://github.com/python/cpython/issues/66021#issuecomment-1093658048) 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](https://bugs.python.org/issue?@action=redirect\u0026bpo=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.\n\n### CPython versions tested on:\n\n3.10, 3.12\n\n### Operating systems tested on:\n\nWindows","author":{"url":"https://github.com/james-oldfield-inex","@type":"Person","name":"james-oldfield-inex"},"datePublished":"2025-10-07T10:00:57.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":9},"url":"https://github.com/139689/cpython/issues/139689"}
| route-pattern | /:user_id/:repository/issues/:id(.:format) |
| route-controller | issues |
| route-action | show |
| fetch-nonce | v2:bce58703-da83-c05c-d08a-9b9699ef0a54 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 8D7A:9445B:2BACC48:3AF9849:696AEBAE |
| html-safe-nonce | 2aa67ac1237efa0aa9f933bc8239e6c830223dbb0c048e32d2234a204fbbb914 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4RDdBOjk0NDVCOjJCQUNDNDg6M0FGOTg0OTo2OTZBRUJBRSIsInZpc2l0b3JfaWQiOiIzNzk5OTk2MDAzNjQ5MjUyMjcwIiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | e22ff0f9e21ee71cec2042f14244dd68501ae175053f5f2664495d263e6389d1 |
| hovercard-subject-tag | repository:81598961 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/python/cpython/issues/139689 |
| twitter:image | https://opengraph.githubassets.com/4bdc75ff44f93fff474a15ea6ea0267a6b07f28bf753fc4d6f632a57d2fa7429/python/cpython |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/4bdc75ff44f93fff474a15ea6ea0267a6b07f28bf753fc4d6f632a57d2fa7429/python/cpython |
| og:image:alt | The Python programming language. Contribute to python/cpython development by creating an account on GitHub. |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 5f99f7c1d70f01da5b93e5ca90303359738944d8ab470e396496262c66e60b8d |
| turbo-cache-control | no-cache |
| go-import | github.com/python/cpython git https://github.com/python/cpython.git |
| octolytics-dimension-user_id | 1525981 |
| octolytics-dimension-user_login | python |
| octolytics-dimension-repository_id | 81598961 |
| octolytics-dimension-repository_nwo | python/cpython |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 81598961 |
| octolytics-dimension-repository_network_root_nwo | python/cpython |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 82560a55c6b2054555076f46e683151ee28a19bc |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width