Dans ce script Python, plusieurs 'cat | Les commandes zgrep sont exécutées séquentiellement sur un serveur distant et leurs sorties sont collectées individuellement pour traitement. Cependant, pour améliorer l'efficacité, nous visons à exécuter ces commandes en parallèle.
Contrairement à l'utilisation du multitraitement ou du threading, vous pouvez exécuter des sous-processus en parallèle en utilisant l'approche suivante :
<code class="python">#!/usr/bin/env python from subprocess import Popen # create a list of subprocesses processes = [Popen("echo {i:d}; sleep 2; echo {i:d}".format(i=i), shell=True) for i in range(5)] # collect statuses of subprocesses exitcodes = [p.wait() for p in processes]</code>
Ce code lance cinq commandes shell simultanément et récupère leurs codes de sortie. Notez que le caractère & n'est pas nécessaire dans ce contexte puisque Popen n'attend pas la fin des commandes par défaut. Vous devez explicitement appeler .wait() pour récupérer leurs statuts.
Bien qu'il soit pratique de collecter les sorties des sous-processus de manière séquentielle, vous pouvez également utiliser des threads pour la collecte parallèle si vous le souhaitez. . Prenons l'exemple suivant :
<code class="python">#!/usr/bin/env python from multiprocessing.dummy import Pool # thread pool from subprocess import Popen, PIPE, STDOUT # create a list of subprocesses with output handling processes = [Popen("echo {i:d}; sleep 2; echo {i:d}".format(i=i), shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) for i in range(5)] # collect outputs in parallel def get_lines(process): return process.communicate()[0].splitlines() outputs = Pool(len(processes)).map(get_lines, processes)</code>
Ce code exécute des sous-processus en parallèle et collecte leurs sorties simultanément à l'aide de threads.
Pour les versions 3.8 et Python ci-dessus, asyncio offre un moyen élégant d'exécuter des sous-processus simultanément. Voici un exemple :
<code class="python">#!/usr/bin/env python3 import asyncio import sys from subprocess import PIPE, STDOUT async def get_lines(shell_command): p = await asyncio.create_subprocess_shell( shell_command, stdin=PIPE, stdout=PIPE, stderr=STDOUT ) return (await p.communicate())[0].splitlines() async def main(): # create a list of coroutines for subprocess execution coros = [get_lines(f'"{sys.executable}" -c "print({i:d}); import time; time.sleep({i:d})"') for i in range(5)] # get subprocess outputs in parallel print(await asyncio.gather(*coros)) if __name__ == "__main__": asyncio.run(main())</code>
Ce code montre comment exécuter des sous-processus simultanément au sein d'un seul thread.
En mettant en œuvre ces approches, vous pouvez améliorer considérablement l'efficacité de votre script en exécutant plusieurs ' chat | zgrep' en parallèle sur le serveur distant.
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!