ContextGroße Menge von multiprocessing.Process verursacht Deadlock
Ich brauche eine multiprocessing.Process in einem multiprocessing.ThreadPool laufen. Es scheint zuerst seltsam, aber es ist die einzige Möglichkeit, die ich mit segfault behandelt, die auftreten könnte, weil ich eine C++ shared Bibliothek verwende. Wenn ein segfault anhängen, wird der Prozess abgebrochen und ich kann den process.exitcode überprüfen und damit umgehen.
Problem
Nach einer Weile ein Deadlock append, wenn ich den Prozess zu verbinden versuchen.
Hier ist eine einfache Version a mein Code:
import sys, time, multiprocessing
from multiprocessing.pool import ThreadPool
def main():
# Launch 8 workers
pool = ThreadPool(8)
it = pool.imap(run, range(500))
while True:
try:
it.next()
except StopIteration:
break
def run(value):
# Each worker launch it own Process
process = multiprocessing.Process(target=run_and_might_segfault, args=(value,))
process.start()
while process.is_alive():
sys.stdout.write('.')
sys.stdout.flush()
time.sleep(0.1)
# Will never join after a while, because of a mystery deadlock
process.join()
# Deals with process.exitcode to log errors
def run_and_might_segfault(value):
# Load a shared library and do stuff (could throw c++ exception, segfault ...)
print(value)
if __name__ == '__main__':
main()
Und hier ist eine mögliche Ausgabe:
➜ ~ python m.py
..0
1
........8
.9
.......10
......11
........12
13
........14
........16
........................................................................................
Wie Sie sehen können, process.is_alive()
nach wenigen Iterationen alway wahr ist, wird der Prozess niemals beitreten.
Wenn ich CTRL-C das Skript ein dieses stacktrace erhalten:
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/multiprocessing/pool.py", line 680, in next
item = self._items.popleft()
IndexError: pop from an empty deque
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "m.py", line 30, in <module>
main()
File "m.py", line 9, in main
it.next()
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5 /lib/python3.5/multiprocessing/pool.py", line 684, in next
self._cond.wait(timeout)
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5 /lib/python3.5/threading.py", line 293, in wait
waiter.acquire()
KeyboardInterrupt
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5 /lib/python3.5/multiprocessing/popen_fork.py", line 29, in poll
pid, sts = os.waitpid(self.pid, flag)
KeyboardInterrupt
PS mit Python 3.5.2 auf Mac OS.
Jede Art von Hilfe ist zu schätzen, danke.
bearbeiten
Ich habe versucht, mit Python 2.7, und es ist gut zu arbeiten. Kann nur ein Python 3.5 Problem auftreten?