首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python多处理:如何度量工作人员中子进程的运行时?

Python多处理:如何度量工作人员中子进程的运行时?
EN

Stack Overflow用户
提问于 2019-01-15 00:42:29
回答 1查看 1.2K关注 0票数 0

work_one()成为这样的函数:

代码语言:javascript
复制
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,我们调用如下函数:

代码语言:javascript
复制
   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倍。

问题:

  1. 如何正确地实现work_one()以获得良好的运行时度量,同时知道work_one()可能同时运行?
  2. 如果子进程work_one()没有在T秒内完成,我还希望T尽早返回,因此os.wait*()函数似乎不是一个好的解决方案,因为它们阻塞了父进程。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-15 01:10:10

一个进程有几个相关的时间;下面是如何获得它们的所有时间(请参阅What do 'real', 'user' and 'sys' mean in the output of time(1)?;tl;dr:用于您的进程的总时间是user_time + system_time):

代码语言:javascript
复制
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返回任何东西,只返回我的测试用例;也许它需要一个更长的过程,或者我做错了什么。

代码语言:javascript
复制
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)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54191234

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档