Python3 具有自己超时的并行进程
Python3 parallel processes with their own timeouts
我有一个要求,我必须启动多个应用程序,无限地获取它们的每个 stdout、stderr 和这些应用程序 运行。这些进程没有 exchange/share 数据并且彼此独立。要进行可变压力测试,它们的超时可能会有所不同。
For eg:
app1 -> 70sec
app2 -> 30sec
.
.
appN -> 20sec
如果这些是具有一个共同超时的多个应用程序,我会将其包装在一个定时的 while 循环中,并在最后终止所有进程。
以下是我认为应该有效的一些方法:
- 每个应用程序都有一个计时器线程,它读取标准输出并在它过期后立即终止进程。进程在线程内启动
- 一个计时器线程循环遍历每个进程的 pid/process_objects:end_time 的字典,并在其 end_time >= 当前时间
时终止进程
我尝试过使用 asyncio gather,但它不能完全满足我的需求,而且我在 Windows 上遇到了一些问题。
还有其他我可以使用的方法吗?
第二个选项非常适合生产。有一个控制循环,您可以在其中轮询要完成的进程并在它们超时时杀死它们
这是第二种方法的代码(扩展)。
#!/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()
我有一个要求,我必须启动多个应用程序,无限地获取它们的每个 stdout、stderr 和这些应用程序 运行。这些进程没有 exchange/share 数据并且彼此独立。要进行可变压力测试,它们的超时可能会有所不同。
For eg:
app1 -> 70sec
app2 -> 30sec
.
.
appN -> 20sec
如果这些是具有一个共同超时的多个应用程序,我会将其包装在一个定时的 while 循环中,并在最后终止所有进程。
以下是我认为应该有效的一些方法:
- 每个应用程序都有一个计时器线程,它读取标准输出并在它过期后立即终止进程。进程在线程内启动
- 一个计时器线程循环遍历每个进程的 pid/process_objects:end_time 的字典,并在其 end_time >= 当前时间 时终止进程
我尝试过使用 asyncio gather,但它不能完全满足我的需求,而且我在 Windows 上遇到了一些问题。
还有其他我可以使用的方法吗?
第二个选项非常适合生产。有一个控制循环,您可以在其中轮询要完成的进程并在它们超时时杀死它们
这是第二种方法的代码(扩展)。
#!/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()