让work_one()
像这样:
def work_one(program_path):
task = subprocess.Popen("./" + program_path, shell=True)
t = 0
while True:
ret = task.poll()
if ret != None or t >= T: # T is the max time we allow for 'task'
break;
else:
t += 0.05
time.sleep(0.05)
return t
有许多此类程序可馈送给work_one()
。当这些程序按顺序运行时,每个work_one()
报告的时间是每个程序运行时的可靠粗略度量。
但是,假设我们有一个multiprocessing.Pool()
实例,其中包含20个工作线程pool
,我们这样调用函数:
def work_all(programs):
pool = multiprocessing.Pool(20)
ts = pool.map(work_one, programs)
return ts
现在,work_all()
报告的运行时度量大约是连续work_one()
报告的运行时度量的20倍。
这是合理的,因为在work_one()
中,当工作进程将0.05
添加到t
并屈服(通过调用time.sleep()
)时,它可能无法屈服到它正在管理的子流程(task
)(不一样,只有一个工人时);取而代之的是,操作系统可能决定将CPU交给另一个并发工作进程。因此,worker_one()
内的迭代次数可能是task
完成之前的20倍。
问题:
work_one()
可能正在同时运行,如何正确实施work_one()
以获得良好的运行时度量?work_one()
在task
秒内未完成,我也希望T
早点返回,因此os.wait*()
函数似乎不是一个好的解决方案,因为它们会阻塞父进程。答案 0 :(得分:1)
一个过程有几个相关的时间;这是全部获取方法(请参见What do 'real', 'user' and 'sys' mean in the output of time(1)?; tl; dr:您的进程占用的CPU总时间为user_time + system_time
):
import time
import os
import subprocess
def work_one(program_path):
start = time.perf_counter()
task = subprocess.Popen(program_path, shell=True)
pid, exit_status, resource_usage = os.wait4(task.pid, 0)
end = time.perf_counter()
real_time = end - start
user_time = resource_usage.ru_utime
system_time = resource_usage.ru_stime
return (real_time, user_time, system_time)
编辑:已修改以提供超时。但是,我无法让resource.getrusage
在测试用例中返回零。也许需要更长的时间,或者我做错了事。
def timeout_handler(signum, frame):
raise TimeoutError()
timeout = 2
def work_one(program_path):
try:
timed_out = False
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(timeout)
start = time.perf_counter()
task = subprocess.Popen(program_path, shell=True)
pid, exit_status, resource_usage = os.wait4(task.pid, 0)
except TimeoutError:
timed_out = True
resource_usage = resource.getrusage(resource.RUSAGE_CHILDREN)
os.kill(task.pid, signal.SIGTERM)
finally:
signal.alarm(0)
end = time.perf_counter()
real_time = end - start
user_time = resource_usage.ru_utime
system_time = resource_usage.ru_stime
return (timed_out, real_time, user_time, system_time)