-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
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
nogil inconsistent empty list while sorting #126559
Comments
I don't think this is worth changing. Python, since at least Python 2.x days, has temporarily made the list appear empty when sorting in place. This can be visible to other threads depending on the types of objects or if the element comparison is implemented in Python. Lines 2831 to 2839 in 09d6f5d
|
I'm not sure we would need to mess with how the list gets sorted--the easier fix would be to lock the list during execution of |
Is it possible to move this: Lines 2831 to 2839 in 09d6f5d
To after the pre-sort check here: Line 2971 in 09d6f5d
And only if the comparator used is custom? That would still cause other threads to see the list as empty while the list is being sorted using a Python comparator, but that feels less surprising and more consistent than the current approach. It can also be documented as part of the expected behavior when using Python comparators. |
Yes, we could do something like that. It would mean that sorting lists of strings, ints, and floats would essentially be atomic, but list of other types (or lists of mixed types) would still not be atomic, even if they are atomic in the GIL-enabled build. |
Hmm, not sure if that's a good option. I understand the value of not locking to read the size of a list, that sounds like a very common operation that should be fast. Here's a concurrent-friendly alternative:
This seems to be fast in the common case, backwards compatible with the zero length behavior, and allows for sorting to be atomic. |
I'm not enthusiastic about further changes to the length field. That has the potential to leak complexity into other list APIs or direct accesses to For additional context, the "empty list behavior" is documented:
Here's a sketch of an alternative. I still don't think it's worthwhile, but it keeps the complexity confined to places that I'm more comfortable with. The underlying ideas are:
To implement this:
As I wrote above, I still don't think this is worthwhile. I don't want to extend |
Bug report
Bug description:
Hi,
We're a research group focused on testing concurrent runtimes. Our work-in-progress prototype found a violation of atomicity on the current nogil build when using concurrent operations on the same list. The program below shows the wrong behavior.
A list with 300 integers is sorted in
t3
while another thread either gets the size of the listt1
or turns the list into a stringt2
. Running the code above will show threadst1
andt2
finding an inconsistent empty list with length 0 or turned into the string"[]"
.Our tool did not find any other interesting values: either it's an expected value (original list or sorted list) OR it's empty.
Sample output:
We're happy to provide more details about this bug, and to help developers reproducing it.
Output of python -VV:
Python 3.14.0a1+ experimental free-threading build (heads/main:faa3272fb8d, Oct 29 2024, 09:14:25) [GCC 14.2.1 20240805]
@flypoodles and @overlorde are part of the team, adding them so they get notified about further discussion.
I believe this issue is part of the ongoing conversation on #126136 about acceptable behaviors of containers operated by many threads concurrently, described in the original nogil PEP: https://peps.python.org/pep-0703/#container-thread-safety
CPython versions tested on:
3.13, 3.14, CPython main branch
Operating systems tested on:
Linux
The text was updated successfully, but these errors were encountered: