使用子进程时如何限制程序的执行时间?

发布于 2024-09-29 17:50:31 字数 628 浏览 2 评论 0原文

我想使用子进程来运行程序,并且需要限制执行时间。例如,如果它运行超过2秒我想杀死它。

对于普通程序,kill() 效果很好。但是,如果我尝试运行 /usr/bin/time some,kill() 无法真正杀死该程序。

我下面的代码似乎不能很好地工作。该程序仍在运行。

import subprocess
import time

exec_proc = subprocess.Popen("/usr/bin/time -f \"%e\\n%M\" ./son > /dev/null", stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell = True)

max_time = 1
cur_time = 0.0
return_code = 0
while cur_time <= max_time:
    if exec_proc.poll() != None:
        return_code = exec_proc.poll()
        break
    time.sleep(0.1)
    cur_time += 0.1

if cur_time > max_time:
    exec_proc.kill()

I want to use subprocess to run a program and I need to limit the execution time. For example, I want to kill it if it runs for more than 2 seconds.

For common programs, kill() works well. But if I try to run /usr/bin/time something, kill() can’t really kill the program.

My code below seems doesn’t work well. The program is still running.

import subprocess
import time

exec_proc = subprocess.Popen("/usr/bin/time -f \"%e\\n%M\" ./son > /dev/null", stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell = True)

max_time = 1
cur_time = 0.0
return_code = 0
while cur_time <= max_time:
    if exec_proc.poll() != None:
        return_code = exec_proc.poll()
        break
    time.sleep(0.1)
    cur_time += 0.1

if cur_time > max_time:
    exec_proc.kill()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半衾梦 2024-10-06 17:50:31

如果您使用的是 Python 2.6 或更高版本,则可以使用 multiprocessing 模块。

from multiprocessing import Process

def f():
    # Stuff to run your process here

p = Process(target=f)
p.start()
p.join(timeout)
if p.is_alive():
    p.terminate()

实际上,多处理是执行此任务的错误模块,因为它只是控制线程运行时间的一种方法。您无法控制线程可能运行的任何子线程。正如奇点所暗示的那样,使用 signal.alarm 是正常的方法。

import signal
import subprocess

def handle_alarm(signum, frame):
    # If the alarm is triggered, we're still in the exec_proc.communicate()
    # call, so use exec_proc.kill() to end the process.
    frame.f_locals['self'].kill()

max_time = ...
stdout = stderr = None
signal.signal(signal.SIGALRM, handle_alarm)
exec_proc = subprocess.Popen(['time', 'ping', '-c', '5', 'google.com'],
                             stdin=None, stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT)
signal.alarm(max_time)
try:
    (stdout, stderr) = exec_proc.communicate()
except IOError:
    # process was killed due to exceeding the alarm
finally:
    signal.alarm(0)
# do stuff with stdout/stderr if they're not None

If you're using Python 2.6 or later, you can use the multiprocessing module.

from multiprocessing import Process

def f():
    # Stuff to run your process here

p = Process(target=f)
p.start()
p.join(timeout)
if p.is_alive():
    p.terminate()

Actually, multiprocessing is the wrong module for this task since it is just a way to control how long a thread runs. You have no control over any children the thread may run. As singularity suggests, using signal.alarm is the normal approach.

import signal
import subprocess

def handle_alarm(signum, frame):
    # If the alarm is triggered, we're still in the exec_proc.communicate()
    # call, so use exec_proc.kill() to end the process.
    frame.f_locals['self'].kill()

max_time = ...
stdout = stderr = None
signal.signal(signal.SIGALRM, handle_alarm)
exec_proc = subprocess.Popen(['time', 'ping', '-c', '5', 'google.com'],
                             stdin=None, stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT)
signal.alarm(max_time)
try:
    (stdout, stderr) = exec_proc.communicate()
except IOError:
    # process was killed due to exceeding the alarm
finally:
    signal.alarm(0)
# do stuff with stdout/stderr if they're not None
独享拥抱 2024-10-06 17:50:31

在命令行中这样做:

perl -e 'alarm shift @ARGV; exec @ARGV' <timeout> <your_command>

这将运行命令 并在 秒后终止。

一个虚拟示例:

# set time out to 5, so that the command will be killed after 5 second 
command = ['perl', '-e', "'alarm shift @ARGV; exec @ARGV'", "5"]

command += ["ping", "www.google.com"]

exec_proc = subprocess.Popen(command)

或者您可以使用 signal.alarm() if你想要用 python 但它是一样的。

do it like so in your command line:

perl -e 'alarm shift @ARGV; exec @ARGV' <timeout> <your_command>

this will run the command <your_command> and terminate it in <timeout> second.

a dummy example :

# set time out to 5, so that the command will be killed after 5 second 
command = ['perl', '-e', "'alarm shift @ARGV; exec @ARGV'", "5"]

command += ["ping", "www.google.com"]

exec_proc = subprocess.Popen(command)

or you can use the signal.alarm() if you want it with python but it's the same.

向日葵 2024-10-06 17:50:31

我使用 os.kill() 但不确定它是否适用于所有操作系统。
伪代码如下,请参阅 Doug Hellman 的页面。

proc = subprocess.Popen(['google-chrome'])                                               
os.kill(proc.pid, signal.SIGUSR1)</code>

I use os.kill() but am not sure if it works on all OSes.
Pseudo code follows, and see Doug Hellman's page.

proc = subprocess.Popen(['google-chrome'])                                               
os.kill(proc.pid, signal.SIGUSR1)</code>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文