2

我试图用来setrlimit()限制一个过程所花费的时间。但是,当我执行某些操作(例如printf().

这是一个说明问题的测试程序:

#include <sys/resource.h>
#include <stdio.h>

int main(void) {
    int i;
    struct rlimit limit;
    limit.rlim_cur = 3;
    limit.rlim_max = 3; // send SIGKILL after 3 seconds 
    setrlimit(RLIMIT_CPU, &limit);

    // doesn't get killed
    for(i=0; i<1000000; i++)
        printf("%d",i);

    return 0;
}

但是,如果我用一个不同的例程替换 for 循环,比如天真的斐波那契:

int fib(int n) {
    if(n<=1) return 1;
    return fib(n-1)+fib(n-2);
}
int main(void) {
    ...
    fib(100);
    ...
}

它完美地工作。这里发生了什么?setrlimit()简直不靠谱?

4

2 回答 2

9

CPU 限制是对CPU秒数而不是经过时间的限制。CPU 秒数基本上是 CPU 已经使用了多少秒,不一定与经过的时间直接相关。

当您进行fib调用时,您会敲击 CPU,以使经过的时间和 CPU 时间接近(大部分处理时间都花费在 CPU 上)。打印时并非如此,因为大部分时间都花在了 I/O 上。

因此,在您的特定情况下发生的事情是rlimit 设置,但您只是在进程完成之前没有使用您的三秒 CPU 时间。

更改main如下会导致信号在我的系统上传递:

int main(void) {
    int i;
    struct rlimit limit;
    limit.rlim_cur = 3;
    limit.rlim_max = 3; // send SIGKILL after 3 seconds
    setrlimit(RLIMIT_CPU, &limit);

    while (1) {                      // Run "forever".
        for(i=0; i<100000; i++) {
            printf("%d\n",i);
        }
        fib(30);                     // some CPU-intensive work.
    }

    return 0;
}

当你time在 Linux 下,你会看到:

: (much looping).
52670
52671
52672
52673
52674
Killed

real   0m18.719s
user   0m0.944s
sys    0m2.416s

在这种情况下,它花费了将近 20 秒的时间,但 CPU 只使用了 3.36 秒(用户 + 系统)。

于 2012-07-26T01:36:40.543 回答
2

rlimit 设置在 CPU 时间上,而不是墙上时间。根据输出的去向,您的程序可能大部分时间都在等待输出设备。在这样做的同时,它不会消耗 CPU 时间。所以程序可能运行时间超过 3 秒,但是如果你检查它的 CPU 使用率(ps up $PID并在下面查看TIME),它会显示使用时间少于 3 秒。

于 2012-07-26T01:30:23.750 回答