Skip to content

threading.Thread.join() cannot be interrupted by a Ctrl-C #41740

Description

@nveeser
mannequin
BPO 1167930
Nosy @gvanrossum, @brettcannon, @gildea

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2007-10-30.00:56:32.778>
created_at = <Date 2005-03-21.22:19:14.000>
labels = ['interpreter-core']
title = 'threading.Thread.join() cannot be interrupted by a Ctrl-C'
updated_at = <Date 2007-10-30.00:56:32.776>
user = 'https://bugs.python.org/nveeser'

bugs.python.org fields:

activity = <Date 2007-10-30.00:56:32.776>
actor = 'gvanrossum'
assignee = 'none'
closed = True
closed_date = <Date 2007-10-30.00:56:32.778>
closer = 'gvanrossum'
components = ['Interpreter Core']
creation = <Date 2005-03-21.22:19:14.000>
creator = 'nveeser'
dependencies = []
files = []
hgrepos = []
issue_num = 1167930
keywords = []
message_count = 6.0
messages = ['24747', '24748', '24749', '24750', '24751', '56947']
nosy_count = 5.0
nosy_names = ['gvanrossum', 'brett.cannon', 'phansen', 'nveeser', 'gildea']
pr_nums = []
priority = 'normal'
resolution = 'wont fix'
stage = None
status = 'closed'
superseder = None
type = None
url = 'https://bugs.python.org/issue1167930'
versions = ['Python 2.5']

Activity

  1. nveeser commented on Mar 21, 2005

    nveesermannequin
    MannequinAuthor

    I write a python program that that starts several
    threads and then waits on them all. If I use join() to
    wait on the threads, there is no way to Stop the
    process with Ctrl-C.

    Threading.Thread.join() uses a lock
    (thread.allocate_lock()) to put itself on the
    "wait_queue". It then calls thread.Lock.acquire(),
    which blocks indefinitely. Lock.acquire() (at least in
    POSIX) seems to work in such a way as to ignore any
    signals. (both semaphore and condition variable type).

    PyThread_acquire_lock() will not return until the lock
    is acquired, even if a signal is sent. Effectively,
    Ctrl-C is "masked" until the lock is released, (the
    joined thread is done), and the main thread comes back
    to the interpreter and handles the signal, producing a
    KeyboardInterrupt Exception. But not before the lock
    is released, which is once the thread is finished,
    which is too late if you want to kill the main thread
    and have it gracefully stop its child threads.

    So the "main" thread has no way to call, join() and
    still respond to Ctrl-C in some way.

    One solution could be to change threading.Thread.join()
    to use other methods of synchronization which respond
    to Ctrl-C more effectively.

    Another solution would be to have Lock.acquire() throw
    a KeyboardInterruped exception like other system calls.
    This IHMO would make the python objects behave more
    like Java, which requires catching the
    InterruptedException, giving the developer more control
    over how to handle this case.

  2. phansen commented on Mar 26, 2005

    phansenmannequin
    Mannequin

    Logged In: YES
    user_id=567267

    Coincidentally this issue came up in a thread in
    comp.lang.python just now. See tim one's reply at
    http://groups.google.ca/groups?selm=mailman.884.1111815188.1799.python-list%40python.org
    which indicates that "it's simply not possible for Ctrl+C to
    interrupt a mutex acquire".

    A workaround is to be sure to call join() with a timeout
    value, inside a loop if you absolutely need an indefinite
    timeout, but that won't necessarily work because of a
    different problem which I just reported as bug 1171023.
    There's a workaround for that problem too though, provided
    you can subclass threading.Thread: provide your own join()
    which wraps the builtin one and which attempts to release
    the lock safely. I'll attach an example if I can figure out
    how... there's no option to do so on this particular page in
    Sourceforge. :-(

  3. phansen commented on Mar 26, 2005

    phansenmannequin
    Mannequin

    Logged In: YES
    user_id=567267

    It appears only the original submitter (and admins?) can
    attach files, so I've attached the example workaround in the
    other bug report that I submitted. It makes more sense in
    that one anyway.

  4. brettcannon commented on Mar 27, 2005

    @brettcannon
    Member

    Logged In: YES
    user_id=357491

    The other bug report phansen is talking about is bug bpo-1171023 (http://
    www.python.org/sf/1171023). Closed as a duplicate but it can still be used
    for file uploads by phansen.

    Also worth reading for its explanation.

  5. gildea commented on Jul 28, 2007

    gildeamannequin
    Mannequin

    The workaround of calling join() with a timeout has a drawback:
    Python's threading wait routine polls 20 times a second when
    given any timeout. All this polling can mean lots of CPU
    interrupts/wakeups on an otherwise idle laptop and drain the
    battery faster.

  6. gvanrossum commented on Oct 30, 2007

    @gvanrossum
    Member

    This is because the regular acquire() method on a basic lock cannot be
    interrupted. That's unlikely to go away, so you'll just have to live
    with this. As you've discovered, specifying a timeout solves the issue
    (sort of).

  7. transferred this issue fromon Apr 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions