Maison > Article > développement back-end > Comment gérer et contrôler efficacement la concurrence des sous-processus bash parallèles en Python ?
Sous-processus Bash parallèles avec Python : un guide complet
L'utilisation efficace des modules de threading et de sous-processus Python peut vous aider à exécuter plusieurs processus bash simultanément. Cependant, la simple création de threads avec threading peut ne pas atteindre le parallélisme souhaité.
Gestion des processus simultanés sans threads
Une approche simple pour exécuter simultanément des processus bash consiste à éviter d'utiliser des threads. tout à fait. À l'aide de l'utilitaire subprocess.Popen, vous pouvez appeler directement plusieurs commandes en parallèle, comme illustré ci-dessous :
<code class="python">from subprocess import Popen commands = [ 'date; ls -l; sleep 1; date', 'date; sleep 5; date', 'date; df -h; sleep 3; date', 'date; hostname; sleep 2; date', 'date; uname -a; date', ] # Execute commands concurrently processes = [Popen(cmd, shell=True) for cmd in commands]</code>
Contrôle de la concurrence avec le multitraitement
Si vous devez limiter En fonction du nombre de processus simultanés, vous pouvez utiliser multiprocessing.dummy.Pool, qui fournit une interface basée sur des threads similaire à multiprocessing.Pool. Le code suivant illustre cette approche :
<code class="python">from functools import partial from multiprocessing.dummy import Pool from subprocess import call pool = Pool(2) # Limit to 2 concurrent processes for i, returncode in enumerate(pool.imap(partial(call, shell=True), commands)): if returncode != 0: print("%d command failed: %d" % (i, returncode))</code>
Gestion des processus enfants non bloquants
Vous pouvez également limiter les processus enfants simultanés sans recourir à des pools de threads ou de processus. Le code ci-dessous illustre cette stratégie :
<code class="python">from subprocess import Popen from itertools import islice max_workers = 2 # Maximum number of concurrent processes processes = (Popen(cmd, shell=True) for cmd in commands) running_processes = list(islice(processes, max_workers)) # Start initial processes while running_processes: for i, process in enumerate(running_processes): if process.poll() is not None: # Process has completed running_processes[i] = next(processes, None) # Start new process if running_processes[i] is None: # No new processes del running_processes[i] break</code>
Pour les systèmes Unix, envisagez d'utiliser os.waitpid(-1, 0) pour éviter les boucles occupées et attendez la fin de tout processus enfant.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!