определенное количество одновременно запущенных процессов

Рейтинг: 0Ответов: 2Опубликовано: 04.02.2023

Такой код запускает 32 пинг завершающихся в разное время,

import random
import subprocess
from threading import Thread
results = []
start_processes = 32
def run_command(count, result_storage):
    cmd = str(subprocess.check_output(['ping', '-c', f'{body}', 'google.' + 'com'], text=True))
    result_storage.append(cmd)
threads = []
for _ in range(start_processes):
    ch = random.choices('1234567890', k=2)
    body = (''.join(ch))
    print(body)
    t = Thread(target=run_command, args=[body, results])
    t.start()
    threads.append(t)
for t in threads:
    t.join()

Необходимо после завершения одного из процессов запускать новый, поддерживая заданное количество процессов..

Ответы

▲ 0

Для вашего кода это можно сделать зациклив поток и генерируя параметры внутри так:

def run_command(result_storage):
    while True:
        ch = random.choices('1234567890', k=2)
        body = (''.join(ch))
        print(body)
        cmd = str(
            subprocess.check_output(
                ['ping', '-c', f'{body}', 'google.' + 'com'],
                text=True
            )
        )
        result_storage.append(cmd)

threads = []
for _ in range(start_processes):
    t = Thread(target=run_command, args=[results])
    t.start()
    threads.append(t)
for t in threads:
    t.join()

При постановке задаче "запустить и не останавливать" сам запуск можно упростить:

from concurrent.futures import ThreadPoolExecutor

with ThreadPoolExecutor(max_workers=start_processes) as executor:
    executor.map(run_command, start_processes * [result])

По-хорошему нужно иметь возможность остановить. Для этого в цикле условие while True: заменить на while not stopped: и переменную stopped устанавливать в True, например, в обработчике Ctrl-C.

▲ 0

Чтоб ThreadPoolExecutor().map() не завершался ему можно скормить генератор. Чтоб не переполнялся results достаем ответы прямо из мап.

from concurrent.futures import ThreadPoolExecutor

def run_command(body):
    cmd = str(subprocess.check_output(['ping', '-c', f'{body}', 'google.' + 'com'], text=True))
    return cmd

def bodygen():
    ch = random.choices('1234567890', k=2)
    body = (''.join(ch))
    yield body

with ThreadPoolExecutor(max_workers=start_processes) as executor:
    for result in executor.map(run_command, bodygen()):
        print(result)

Ещё более мощный, но синхронный интерфейс к тредам в multiprocessing.dummy.Pool().