В этом скрипте Python несколько символов 'cat | Команды zgrep выполняются последовательно на удаленном сервере, а их выходные данные собираются индивидуально для обработки. Однако для повышения эффективности мы стремимся выполнять эти команды параллельно.
В отличие от использования многопроцессорной обработки или многопоточности, вы можете выполнять подпроцессы параллельно, используя следующий подход:
#!/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]
Этот код одновременно запускает пять команд оболочки и собирает их коды завершения. Обратите внимание, что символ & в этом контексте не обязателен, поскольку Popen по умолчанию не ждет завершения команд. Вы должны явно вызвать .wait() для получения их статусов.
Хотя удобно собирать выходные данные из подпроцессов последовательно, при желании вы также можете использовать потоки для параллельного сбора . Рассмотрим следующий пример:
#!/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)
Этот код запускает подпроцессы параллельно и собирает их выходные данные одновременно с использованием потоков.
Для версий Python 3.8 и выше asyncio предлагает элегантный способ одновременного выполнения подпроцессов. Вот пример:
#!/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())
Этот код демонстрирует, как одновременно запускать подпроцессы в одном потоке.
Реализуя эти подходы, вы можете значительно повысить эффективность своего скрипта, выполняя несколько 'кот | zgrep' параллельно на удаленном сервере.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3