Skip to content

_thread module docs: update yet another bullet point in the *caveats* list #125058

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
zuo opened this issue Oct 7, 2024 · 13 comments
Closed

_thread module docs: update yet another bullet point in the *caveats* list #125058

zuo opened this issue Oct 7, 2024 · 13 comments
Labels
docs Documentation in the Doc dir

Comments

@zuo
Copy link
Contributor

zuo commented Oct 7, 2024

Documentation

[Note: This issue is, in a way, a continuation of gh-125025.]

Near the end of the documentation of the _thread module there is a list of caveats. One of them – the third one – seems no longer accurate:

It is not possible to interrupt the acquire() method on a lock — the KeyboardInterrupt exception will happen after the lock has been acquired.

whereas it appears that (since Python 3.2) lock acquisitions can be interrupted by signals, at least on platforms using Pthreads.

Linked PRs

@zuo zuo added the docs Documentation in the Doc dir label Oct 7, 2024
@zuo
Copy link
Contributor Author

zuo commented Oct 7, 2024

The question is whether nowadays the possibility to interrupt a blocking acquisition of a lock is possible only on POSIX systems (I can observe that on my Linux system), or maybe also on others? (i.e., Windows?)

Unfortunately I am not sure what is the right answer, therefore a Python threading expert needs to speak up.

According to the Experts Index the right persons are you, @gpshead and @pitrou. I hope, this is the right way to ask you for help?

Thank you in advance! :)

@zuo
Copy link
Contributor Author

zuo commented Oct 7, 2024

PS I'd happy to provide a PR with an appropriate docs patch – when I'm sure what is the state of affairs when it comes the possibility to interrupt a lock acquisition on platforms with a non-Pthreads-based threads implementation.

@gpshead
Copy link
Member

gpshead commented Oct 7, 2024

Yes POSIXish platforms should happily allow interrupting threading.Lock.acquire() with ^C at this point. @zooba or @eryksun wear Windows hats and can answer for that platform.

@zooba
Copy link
Member

zooba commented Oct 7, 2024

Looks like Windows is using EnterNonRecursiveMutex() for this, which is not going to be interruptible (based on a quick look - trust Eryk's opinion over mine here).

In order to be interruptible, it needs to be a WaitForMultipleObjects including the _PyOS_SigintEvent handle. I don't think it's trivial to convert, at least not without a performance loss, and likely with subtle behaviour changes from what it currently does.

@zuo
Copy link
Contributor Author

zuo commented Oct 8, 2024

@gpshead @zooba Thank you for your feedback! I presume that something along the lines of the following would be appropriate:

It is platform-dependent whether the acquire() method on a lock can be interrupted (so that the KeyboardInterrupt exception will happen immediately, rather than only after the lock has been acquired or the operation has timed out).

@zuo
Copy link
Contributor Author

zuo commented Oct 8, 2024

PS Perhaps adding that

It can on POSIX platforms.

@pitrou
Copy link
Member

pitrou commented Oct 8, 2024

In order to be interruptible, it needs to be a WaitForMultipleObjects including the _PyOS_SigintEvent handle.

I think this used to be the case, but it got replaced by the faster native mutex for performance.

@colesbury
Copy link
Contributor

colesbury commented Oct 8, 2024

@kumaraditya303 has a PR to use PyMutex for _thread.lock, which blocks using an alertable (interruptible?) WaitForSingleObjectEx call:

@colesbury
Copy link
Contributor

My previous comment was incorrect. PyMutex calls WaitForSingleObjectEx with bAlertable=FALSE:

wait = WaitForSingleObjectEx(sema->platform_sem, millis, FALSE);

@zuo
Copy link
Contributor Author

zuo commented Oct 8, 2024

OK, so it remains platform-dependent whether acquire() is interruptible, doesn't it?

@pitrou
Copy link
Member

pitrou commented Oct 8, 2024

Yes. But concretely, it's interruptible on POSIX, not on Windows.

@pitrou
Copy link
Member

pitrou commented Oct 8, 2024

My previous comment was incorrect. PyMutex calls WaitForSingleObjectEx with bAlertable=FALSE:

Regardless, it seems the bAlertable flag has nothing to do with being interruptible with Ctrl-C:
https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobjectex

If this parameter is TRUE and the thread is in the waiting state, the function returns when the system queues an I/O completion routine or APC, and the thread runs the routine or function. Otherwise, the function does not return, and the completion routine or APC function is not executed.

@zuo
Copy link
Contributor Author

zuo commented Oct 8, 2024

PR is ready :)

miss-islington pushed a commit to miss-islington/cpython that referenced this issue Oct 11, 2024
…`lock.acquire()` (pythonGH-125141)

(cherry picked from commit 0135848)

Co-authored-by: Jan Kaliszewski <[email protected]>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Oct 11, 2024
…`lock.acquire()` (pythonGH-125141)

(cherry picked from commit 0135848)

Co-authored-by: Jan Kaliszewski <[email protected]>
kumaraditya303 pushed a commit that referenced this issue Oct 11, 2024
… `lock.acquire()` (GH-125141) (#125306)

gh-125058: update `_thread` docs regarding interruptibility of `lock.acquire()` (GH-125141)
(cherry picked from commit 0135848)

Co-authored-by: Jan Kaliszewski <[email protected]>
kumaraditya303 pushed a commit that referenced this issue Oct 11, 2024
… `lock.acquire()` (GH-125141) (#125307)

gh-125058: update `_thread` docs regarding interruptibility of `lock.acquire()` (GH-125141)
(cherry picked from commit 0135848)

Co-authored-by: Jan Kaliszewski <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir
Projects
None yet
Development

No branches or pull requests

6 participants