C - 设置限制不可靠?



我正在尝试使用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循环,比如naive fibonacci:

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

它工作得很好。这是怎么回事?setrlimit()就是不可靠吗?

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("%dn",i);
        }
        fib(30);                     // some CPU-intensive work.
    }
    return 0;
}

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

: (much looping).
52670
52671
52672
52673
52674
Killed
real   0m18.719s
user   0m0.944s
sys    0m2.416s

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

rlimit是根据CPU时间而不是墙时间设置的。根据输出的方向,程序可能会将大部分时间花在输出设备上等待。当它这样做的时候,它不会消耗CPU时间。因此,程序运行时间可能超过3秒,但如果您检查其CPU使用情况(ps up $PID并查看TIME),它将显示使用时间不到3秒。

最新更新