Skip to content

Creating multiprocessing.Queues operates strangely with Process's created in classes #123208

Description

@Moosems

Bug report

Bug description:

The following from the docs works:

frommultiprocessingimportProcess, Queuedeff(q):
q.put([42, None, 'hello'])
if__name__=='__main__':
q=Queue()
p=Process(target=f, args=(q,))
p.start()
print(q.get()) # prints "[42, None, 'hello']"p.join()

The following also works:

frommultiprocessingimportProcess, Queuefromtimeimportsleepdeff(q):
passif__name__=='__main__':
q=Queue()
p=Process(target=f, args=(q,))
p.start()
sleep(1)

This works just fine:

classFoo:
def__init__(self, q) ->None:
passif__name__=='__main__':
q=Queue()
p=Process(target=Foo, args=(q,))
p.start()
sleep(1)

But the following does NOT work:

frommultiprocessingimportProcess, QueuefromtimeimportsleepclassFoo:
def__init__(self, q) ->None:
passclassBar:
def__init__(self) ->None:
q=Queue()
p=Process(target=Foo, args=(q,))
p.start()
if__name__=='__main__':
Bar()
sleep(1)

Which now gives this traceback:

Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/Cellar/python@3.12/3.12.4/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/spawn.py", line 122, in spawn_main
exitcode = _main(fd, parent_sentinel)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/Cellar/python@3.12/3.12.4/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/spawn.py", line 132, in _main
self = reduction.pickle.load(from_parent)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/Cellar/python@3.12/3.12.4/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/synchronize.py", line 115, in __setstate__
self._semlock = _multiprocessing.SemLock._rebuild(*state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory

The following does work, though:

frommultiprocessingimportProcess, QueuefromtimeimportsleepclassFoo:
def__init__(self, q) ->None:
q.put("INIT COMPLETE")
classBar:
def__init__(self) ->None:
q=Queue()
p=Process(target=Foo, args=(q,))
p.start()
q.get()
if__name__=='__main__':
Bar()
sleep(1)

This should either be documented or fixed, preferably the latter. This behavior is strange and, quite frankly, unexpected. It took me quite a while to figure this out and fix my code but adding an init queue item is not ideal. Note that the following also breaks with the same error:

frommultiprocessingimportProcess, Queuefromtimeimportsleepdeffoo(q) ->None:
passclassBar:
def__init__(self) ->None:
q=Queue()
p=Process(target=foo, args=(q,))
p.start()
if__name__=='__main__':
Bar()
sleep(1)

Moving the Queue outside of the class (when calling it) also doesn't fix the issue:

frommultiprocessingimportProcess, Queuefromtimeimportsleepdeffoo(q) ->None:
passclassBar:
def__init__(self, q) ->None:
p=Process(target=foo, args=(q,))
p.start()
if__name__=='__main__':
Bar(Queue())
sleep(1)

But the following works just fine:

frommultiprocessingimportProcess, Queuefromtimeimportsleepdeffoo(q) ->None:
passclassBar:
def__init__(self, q) ->None:
p=Process(target=foo, args=(q,))
p.start()
if__name__=='__main__':
q=Queue()
Bar(q)
sleep(1)

This may be related to #116526 but I don't personally think this should be classified as the same issue. May be related to #23376 as well but this may still be a separate issue. Neither address this kind of behavior, however.

CPython versions tested on:

3.12

Operating systems tested on:

macOS

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions