2012-07-26 94 views
2

我正在嘗試使用setrlimit()來限制進程需要花費的時間。但是,當我執行像printf()這樣的特定操作時,它似乎不起作用。setrlimit不可靠?

這是說明問題的測試程序:

#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()簡直不可靠?

+0

該代碼甚至沒有編譯!讓我爲你解決這個問題。 – paxdiablo 2012-07-26 01:25:23

+0

@paxdiablo:啊謝謝!我做了一些動態編輯:[ – tskuzzy 2012-07-26 01:42:26

回答

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秒(用戶+ sys)。

+1

剩下的時間可能會被阻止,等待您的超慢GNOME/libvte /基於終端的終端完成重繪並再次從pty主設備讀取... :-) – 2012-07-26 03:16:41

+0

那麼你如何限制流逝的時間? – 2014-04-01 00:04:53

+0

@Dustin,你用_another_進程啓動進程,然後監視牆的時間,如果超過了,就殺掉你想限制的那個。 – paxdiablo 2014-04-01 01:10:40

2

rlimit被放置在CPU時間上,而不是牆上時間。根據輸出的進行情況,您的程序可能將大部分時間花費在輸出設備上。雖然這樣做,但不會消耗CPU時間。因此,程序運行時間可能會超過3秒,但如果您檢查其CPU使用率(ps up $PID並在TIME之下查看),它將顯示使用時間少於3秒。