问题描述
|
如何在Bash中将进程限制为少于1秒的cpu时间?我正在使用4.1.5(1)版本,如果键入
ulimit -t 0.5 command
,我将得到:
-bash: ulimit: 0.5: invalid number
我将ulimit -t 1 command
用作不完美的替代品,但是出于技术原因,我不需要打扰您,我非常希望command
在拥有cpu半秒或更短的时间后停止运行。
特定于Linux的答案会很好。
解决方法
就像其他人说的那样,您无法使用标准的内置Bash命令来做到这一点。
可以创建自己的命令来限制命令的运行时间(与该命令使用的实际CPU时间不同;另请参见Rob的评论,谢谢!)。我以前在SO代码上发布过,是在经过整数秒后执行超时(因此这不是直接解决您的问题)。但是,您可以(非常)轻松地修改代码,以对经过的时间和POSIX设施使用亚秒级分辨率。核心接口是:
timeout -t time [-s signal] cmd [args ...]
要满足您的要求,只需识别不到一秒的时间并调用适当的函数即可;它对内部的影响远大于对外部的影响。
从理论上讲(根据POSIX 2008),应使用timer_create()
,timer_settime()
和timer_gettime()
函数。它们提供了对计时器到期时应生成哪个信号的详细控制,等等。但是,并非所有系统都提供它们(例如,MacOS X 10.6.7并未记录它们)。这些使用标头<time.h>
和<signal.h>
,以及struct itimerspec
(和struct sigevent
)。
但是,在短期内,您可能需要改用getitimer()
和setitimer()
函数,而POSIX 2008将该函数标记为已过时(但在MacOS X 10.6.7中可用)。它们使用标题<sys/time.h>
和struct itimerval
。
为了便于移植,您可能需要自动配置程序以处理这两种情况。您可能还需要使用Windows(无疑会提供替代界面)。如果没有高分辨率信令计时器系统可用,您可能会退回到ѭ16和整个秒的粒度计时。如果同时存在*itimer
函数,则选择timer_*
函数;或者先测试timer_*
,然后使用它们(如果可用)。
请注意,如果您使用这些功能将超时设置为0.5秒,则它们将保证经过的最短时间为0.5秒-但由于调度问题,它可能比该时间任意更长。请注意,有一个“ 20”来帮助确定超支的时间。
, 也许你做不到。底层系统调用(setrlimit
)仅提供整秒的分辨率。
RLIMIT_CPU
CPU time limit in seconds. When the process reaches the soft
limit,it is sent a SIGXCPU signal. The default action for this
signal is to terminate the process. However,the signal can be
caught,and the handler can return control to the main program.
If the process continues to consume CPU time,it will be sent
SIGXCPU once per second until the hard limit is reached,at
which time it is sent SIGKILL.
, 你不能。底层的setrlimit调用的粒度为秒。