Wenn ich im folgenden Programm den Prozess an eine Liste anhänge (was scheinbar sinnlos ist), läuft er wie erwartet. Entferne ich jedoch das Anhängen, wird der Destruktor des Prozesses viele Male aufgerufen, bevor er überhaupt ausgeführt wird. Es gibt nur n
Konstruktionen, sondern (n)(n+1)/2
(wobei n
ist die Anzahl der Prozesse) Zerstörungen. Dies führt mich zu der Annahme, dass jeder Prozess in jeden neuen Prozess kopiert und dann sofort zerstört wird. Vielleicht funktioniert das Multiprocessing-Modul so. Das macht Sinn, da jeder Prozess eine Abspaltung des aktuellen Prozesses ist. Aber welche Bedeutung hat das Anhängen an die Liste? Warum wird dieses Verhalten dadurch gestoppt?
Hier sind der Test und die Beispielausgabe:
import multiprocessing
class _ProcSTOP:
pass
class Proc(multiprocessing.Process):
def __init__(self, q, s):
s.i += 1
self._i = s.i
self._q = q
print('constructing:', s.i)
super().__init__()
def run(self):
dat = self._q.get()
while not dat is _ProcSTOP:
self._q.task_done()
dat = self._q.get()
self._q.task_done()
print('returning: ', self._i)
def __del__(self):
print('destroying: ', self._i)
if __name__ == '__main__':
q = multiprocessing.JoinableQueue()
s = multiprocessing.Manager().Namespace()
s.i = 0
pool = []
for i in range(4):
p = Proc(q, s)
p.start()
pool.append(p) # This is the line to comment
for i in range(10000):
q.put(i)
q.join()
for i in range(4):
q.put(_ProcSTOP)
q.join()
print('== complete')
Beispielhafte Ausgabe mit Anhängen:
constructing: 1
constructing: 2
constructing: 3
constructing: 4
returning: 3
returning: 2
== complete
returning: 1
returning: 4
destroying: 4
destroying: 3
destroying: 2
destroying: 1
Beispielhafte Ausgabe ohne Anhängen:
constructing: 1
constructing: 2
constructing: 3
destroying: 1
constructing: 4
destroying: 1
destroying: 2
destroying: 3
destroying: 1
destroying: 2
returning: 1
returning: 4
returning: 2
== complete
returning: 3
destroying: 1
destroying: 3
destroying: 2
destroying: 4