setrlimit不可靠?

tsk*_*zzy 2 c time setrlimit

我试图用来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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

它完美地运作.这里发生了什么?是setrlimit()根本不可靠?

pax*_*blo 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;
}
Run Code Online (Sandbox Code Playgroud)

当你time在Linux下,你看到:

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

real   0m18.719s
user   0m0.944s
sys    0m2.416s
Run Code Online (Sandbox Code Playgroud)

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