je rencontre quelques problèmes à comprendre ce que je passe avec les processus dans le code suivant je l'ai écrit comme une simplification d'un autre script que je vous écris pour se familiariser avec multitraitement:Comment travailler avec la restriction du système d'exploitation sur le nombre maximal de processus dans une fonction de multitraitement récursif?
import multiprocessing
import time
from random import randint
from os import getpid
def f(i, process_id, parent_process_message_queue):
print (i,process_id, getpid())
time.sleep(randint(0,10)/100)
child_processes = []
child_process_message_queue = multiprocessing.Queue()
if randint(0,10) > 4:
child_processes.append(multiprocessing.Process(target = f, args = (i+1, 0, child_process_message_queue)))
child_processes[-1].start()
child_processes.append(multiprocessing.Process(target = f, args = (i+1, 1, child_process_message_queue)))
child_processes[-1].start()
while not child_process_message_queue.empty():
child_id = child_process_message_queue.get()
child_processes[child_id].join()
parent_process_message_queue.put(process_id)
child_process_message_queue = multiprocessing.Queue()
p = multiprocessing.Process(target = f, args = (0, 0, child_process_message_queue))
p.start()
while not child_process_message_queue.empty():
child_id = child_process_message_queue.get()
child_processes[child_id].join()
p.join()
Lorsqu'ils ne sont pas trop récursive les appels arrivent (à cause de l'élément aléatoire) alors ce code semble fonctionner comme prévu.
sortie d'une course réussie ressemble à ceci:
0 0 57756
1 0 57757
1 1 57758
2 0 57759
2 1 57760
3 0 57761
3 1 57762
3 0 57763
3 1 57764
4 0 57765
4 1 57766
4 0 57767
4 1 57768
5 0 57769
5 1 57770
Cependant, lorsque trop d'appels récursifs sont faits, les choses deviennent étranges; des choses comme cela semble, y compris un certain message d'erreur:
Process Process-1:2:1:2:1:2:2:2:2:1:1:1:1:1:1:1:1:2:2:2:2:2:2:1:1:1:2:2:1:1:1:1:2:1:2:1:
Process Process-1:2:1:2:1:2:2:2:2:1:1:1:1:1:1:1:2:2:2:1:2:2:2:1:2:2:2:1:2:2:2:1:1:2:2:2:1:1:1:1:2:
Process Process-1:2:1:2:1:2:2:2:2:1:1:1:1:1:1:1:1:2:2:2:2:2:2:2:2:2:2:2:2:2:1:2:2:2:1:2:2:2:1:2:
Process Process-1:2:1:2:1:2:2:2:2:1:1:1:1:1:1:1:1:2:2:2:1:2:2:2:1:2:1:2:2:1:1:2:2:1:2:2:1:2:1:1:2:1:1:
Process Process-1:2:1:2:2:2:2:1:2:2:2:1:1:1:2:1:2:2:1:2:2:1:1:2:1:1:1:2:1:1:2:2:1:1:1:1:1:1:1:1:2:1:1:2:2:2:2:2:
Traceback (most recent call last):
File "/Users/user/anaconda/lib/python3.6/multiprocessing/process.py", line 249, in _bootstrap
self.run()
File "/Users/user/anaconda/lib/python3.6/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "queuetest2.py", line 18, in f
child_processes[-1].start()
File "/Users/user/anaconda/lib/python3.6/multiprocessing/process.py", line 105, in start
[...]
Traceback (most recent call last):
BlockingIOError: [Errno 35] Resource temporarily unavailable
Je recherchais cette erreur (BlockingIOError: [Errno 35]) et apparemment ce comportement est dû par le scrip essayant de créer plus de processus que permis par le système d'exploitation. Maintenant, je me demande: Quelle est la meilleure façon de gérer cela? Je n'imagine pas que les fonctions récursives qui utilisent le multitraitement soient une mauvaise idée en soi, n'est-ce pas? Une solution peut avoir besoin de vérifier si la limite de processus a déjà été atteinte et, si c'est le cas, de poursuivre la récursivité dans le même thread, sinon, continuez à générer de nouveaux processus, mais est-ce une bonne approche?