-
-
Notifications
You must be signed in to change notification settings - Fork 31.2k
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
bpo-47029: Fix BrokenPipeError in multiprocessing.Queue at garbage collection and explicit close #31913
Conversation
I tried this pull request and didn't fix the problem for me. Might you be getting tricked by how racy this issue is into thinking that an unrelated change is resolving it? I posted this on the issue ticket, but I'll include it here as well. This program pretty reliably reproduces the issue, both on your branch and on upstream: import multiprocessing
import time
def main():
q = multiprocessing.Queue()
q.put(0)
#time.sleep(0.001) # Issue goes away when this line is uncommented
q.close()
q.join_thread()
if __name__ == '__main__':
main() I have tested this with two Linux/x86_64 machines, one running Ubuntu 21.10 with kernel |
Thanks for the code sample @malsyned. I have updated the PR and it now fixes your issue too. The problem in your case was that the function The root of the problem is explained in this paragraph from the Linux manual page of pipe (bold emphasis mine):
|
Thanks for the review @MaxwellDupre! |
@JelleZijlstra can I request your review of this PR since version 3.11 beta 1 is about to be released? It is a bug fix, not a new feature, but I am not sure it can be released in next betas. |
I can try but the multiprocessing module is mostly black magic to me. I'll spend a little time trying to understand what's going on here. Is it possible to add a unit test for this behavior? And do you think it's safe to backport to the 3.9 and 3.10 branches? |
I could add #31913 (comment) as unit test but the problem is that it is subject to a race condition so the test would not be 100% reliable.
I tested this PR on Python 3.9.12 on my MacBook Pro so I think so. |
Thanks @maggyero for the PR, and @JelleZijlstra for merging it 🌮🎉.. I'm working now to backport this PR to: 3.9, 3.10. |
GH-92276 is a backport of this pull request to the 3.10 branch. |
GH-92277 is a backport of this pull request to the 3.9 branch. |
…llection and explicit close (pythonGH-31913) (cherry picked from commit dfb1b9d) Co-authored-by: Géry Ogam <gery.ogam@gmail.com>
Thanks for the review and your amazing reactivity @JelleZijlstra! |
…llection and explicit close (pythonGH-31913) (cherry picked from commit dfb1b9d) Co-authored-by: Géry Ogam <gery.ogam@gmail.com>
Program:
Output:
A
BrokenPipeError
exception is raised when the functionQueue._feed
in the queue thread writes buffered data to the file descriptorself._writer
referring to the write end of the pipe after the garbage collector closes the file descriptorself._reader
referring to the read end of the pipe in the main thread. Note that the garbage collector does not closeself._writer
because it is referenced byQueue._feed
in the queue thread.This PR fixes the problem by passing a reference to
self._reader
toQueue._feed
in the queue thread in order to keep the reader end of the pipe alive until the queue thread stops writing buffered data toself._writer
.https://bugs.python.org/issue47029