I've got the following toy script:
#!/usr/bin/env python3
import multiprocessing as mp
def main():
queue = mp.Queue()
stop = mp.Event()
workers = []
n = mp.cpu_count()
print(f"starting {n} processes")
for i in range(n):
p = mp.Process(target=work, args=(i, queue, stop))
workers.append(p)
p.start()
print("getting 1000 items from queue")
for _ in range(1000):
queue.get()
print("poisoning processes")
stop.set()
print("joining processes")
for worker in workers:
# hangs occassionally if terminate not called
# worker.terminate()
worker.join()
print("closing queue")
queue.close()
print("returning")
def work(i, queue, stop):
while not stop.is_set():
queue.put("something")
print(f"exiting process {i}")
if __name__ == "__main__":
main()
Here is some sample output where it hangs and then I kill it with Ctrl-C:
λ ./mp_template.py
starting 16 processes
getting 1000 items from queue
poisoning processes
joining processes
exiting process 1
exiting process 2
exiting process 0
exiting process 10
exiting process 9
exiting process 7
exiting process 11
exiting process 5
exiting process 12
exiting process 6
exiting process 4
exiting process 13
exiting process 3
exiting process 8
exiting process 14
exiting process 15
^CTraceback (most recent call last):
File "/data/repos/mse-408/./mp_template.py", line 37, in <module>
main()
File "/data/repos/mse-408/./mp_template.py", line 24, in main
worker.join()
File "/usr/lib/python3.10/multiprocessing/process.py", line 149, in join
res = self._popen.wait(timeout)
File "/usr/lib/python3.10/multiprocessing/popen_fork.py", line 43, in wait
return self.poll(os.WNOHANG if timeout == 0.0 else 0)
File "/usr/lib/python3.10/multiprocessing/popen_fork.py", line 27, in poll
pid, sts = os.waitpid(self.pid, flag)
KeyboardInterrupt
Process Process-1:
Traceback (most recent call last):
File "/usr/lib/python3.10/multiprocessing/process.py", line 317, in _bootstrap
util._exit_function()
File "/usr/lib/python3.10/multiprocessing/util.py", line 360, in _exit_function
_run_finalizers()
File "/usr/lib/python3.10/multiprocessing/util.py", line 300, in _run_finalizers
finalizer()
File "/usr/lib/python3.10/multiprocessing/util.py", line 224, in __call__
res = self._callback(*self._args, **self._kwargs)
File "/usr/lib/python3.10/multiprocessing/queues.py", line 199, in _finalize_join
thread.join()
File "/usr/lib/python3.10/threading.py", line 1096, in join
self._wait_for_tstate_lock()
File "/usr/lib/python3.10/threading.py", line 1116, in _wait_for_tstate_lock
if lock.acquire(block, timeout):
KeyboardInterrupt
Why does this occasionally hang and other times not? If I add worker.terminate()
for each worker, it always exits. However, I thought that if the worker returned (as it does after stop.set()
is called) -- why does it hang?
source https://stackoverflow.com/questions/74105679/python-3-10-multiprocessing-hangs-only-sometimes-after-poisoning
Comments
Post a Comment