Python3 параллельных процессов с собственными тайм-аутами - PullRequest
0 голосов
/ 27 марта 2020

У меня есть требование, при котором мне нужно запускать несколько приложений, получать каждое из их stdout, stderr, и эти приложения работают бесконечно. Процессы не обмениваются / обмениваются данными и независимы друг от друга. Чтобы выполнить переменные стресс-тесты, их таймауты могут отличаться.

For eg: 
app1 -> 70sec
app2 -> 30sec
.
.
appN -> 20sec

Если бы это было несколько приложений с одним общим таймаутом, я бы обернул его за время l oop и убил бы все процессы в конец.

Вот несколько подходов, которые, я думаю, должны работать:

  1. Поток таймера для каждого приложения, который читает стандартный вывод и, как только он истекает, завершает процесс. Процесс запускается в потоке
  2. Один поток таймера, который просматривает словарь pid / process_objects: end_time для каждого процесса и убивает процесс, когда его end_time>> = текущее время

Я пытался использовать сборку asyncio, но она не полностью соответствует моим потребностям, и я столкнулся с некоторыми проблемами в Windows.

Есть ли другие подходы, которые я могу использовать?

Ответы [ 2 ]

1 голос
/ 27 марта 2020

Второй вариант довольно готов к производству. Иметь элемент управления l oop, где вы запрашиваете завершение процессов и убиваете их, если они истекают

0 голосов
/ 07 апреля 2020

Вот код для второго подхода (расширенный { ссылка }).

#!/usr/bin/env python
import io
import os
import sys
from subprocess import Popen
import threading
import time
import psutil

def proc_monitor_thread(proc_dict):
    while proc_dict != {}:
        for k,v in list(proc_dict.items()):
            if time.time() > v:
                print("killing " + str(k))
                m = psutil.Process(k)
                m.kill()
                del proc_dict[k]
        time.sleep(2)

pros = {} 

ON_POSIX = 'posix' in sys.builtin_module_names

# create a pipe to get data
input_fd, output_fd = os.pipe()

# start several subprocesses
st_time = time.time()
for i in ["www.google.com", "www.amd.com", "www.wix.com"]:
    proc = Popen(["ping", "-t", str(i)], stdout=output_fd,
                   close_fds=ON_POSIX) # close input_fd in children

    if "google" in i:
        pros[proc.pid] = time.time() + 5
    elif "amd" in i:
        pros[proc.pid] = time.time() + 8
    else:
        pros[proc.pid] = time.time() + 10

os.close(output_fd)
x = threading.Thread(target=proc_monitor_thread, args=(pros,))
x.start()

# read output line by line as soon as it is available
with io.open(input_fd, 'r', buffering=1) as file:
    for line in file:
        print(line, end='')
#

print("End")
x.join()
...