2013-07-18 78 views
0

特別是在SO questionthis answer之後,似乎在printf使其不起作用之後調用setrlimit。printf使setrlimit不起作用

下面是示例代碼:

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

int main() 
{ 
    struct rlimit rlp; 

    FILE *fp[10000]; 
    int i; 

    printf("Hello\n"); 

    rlp.rlim_cur = 10000; 
    rlp.rlim_max = RLIM_INFINITY; 
    setrlimit(RLIMIT_NOFILE, &rlp); 

    getrlimit(RLIMIT_NOFILE, &rlp); 
    printf("limit %lld %lld\n", rlp.rlim_cur, rlp.rlim_max); 

    for(i=0;i<10000;i++) { 
     fp[i] = fopen("a.out", "r"); 
     if(fp[i]==0) { printf("failed after %d\n", i); break; } 
    } 

} 

這裏是控制檯輸出:

Hello 
limit 10000 9223372036854775807 
failed after 4861 

如果我評論的第一printf,這裏是控制檯輸出:

limit 10000 9223372036854775807 
failed after 9967 

這有什麼理由嗎?

[編輯]我正在使用Xcode 4.6.2運行MAc OS X 10.7.5。

+0

1.您的代碼與輸出不匹配。 2.我剛剛在Red Hat 5系統上嘗試過,並且在沒有「Hello」的情況下得到相同的數字。我相信它也將取決於你的系統上還在發生什麼。 – BoBTFish

+0

這是我正在使用的確切代碼。我在Mac OS 10.7上使用Xcode 4.6.2,也許這就是爲什麼。 –

+0

真的嗎?您正在使用的**精確**代碼包含'printf(「...之後)」,但打印出「limit ...」'?你的'printf'實現被嚴重破壞! – BoBTFish

回答

1

下面是程序的更好的版本,展示了更多方面的問題。

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

int 
main(int argc, char **argv) 
{ 
     struct rlimit rl; 
     int i; 

     rl.rlim_cur = 10; 
     rl.rlim_max = RLIM_INFINITY; 
     if (setrlimit(RLIMIT_NOFILE, &rl)) 
       err(1, "setrlimit"); 

     printf("Hello\n"); 

     rl.rlim_cur = 100; 
     rl.rlim_max = RLIM_INFINITY; 
     if (setrlimit(RLIMIT_NOFILE, &rl)) 
       err(1, "setrlimit"); 

     if (getrlimit(RLIMIT_NOFILE, &rl)) 
       err(1, "getrlimit"); 
     printf("limit %lld\n", rl.rlim_cur); 

     for(i = 0; i < 10000; i++) { 
       FILE *fp; 
#if 1 
       if ((fp = fopen("foo", "r")) == NULL) { 
         err(1, "failed after %d", i); 
       } 
#else 
       if (open("foo", O_RDONLY) == -1) { 
         err(1, "failed after %d", i); 
       } 
#endif 
     } 
     return 0; 
} 

如果你用「#如果1」改爲運行此程序「的#if 0」它按預期工作。看起來MacOS在libc中初始化stdio期間讀取一次打開文件的限制,並且稍後不會再讀取它們。您第一次調用printf時,會初始化libdio中的stdio,並緩存打開文件數目的rlimit值。

運行在一個簡單的「你好,世界」顯示dtruss:

$ cat > hw.c 
#include <stdio.h> 
int main() { printf("hello, world\n"); return 0; } 
$ cc -Wall -o hw hw.c && sudo dtruss ./hw 2>&1 | grep rlimit 
getrlimit(0x1008, 0x7FFF58875AE8, 0x7FFF8BE92470)  = 0 0 
$ 

,顯示這實際上是發生了什麼。

這是你應該採取與蘋果雖然,它聞起來像一個錯誤。