簡體   English   中英

如何在Mac OS X上增加C中“最大打開文件”的限制

[英]How to increase the limit of “maximum open files” in C on Mac OS X

Mac OS X上最大打開文件的默認限制為256(ulimit -n),我的應用程序需要大約400個文件處理程序。

我嘗試用setrlimit()更改限制,但即使函數正確執行,我仍然限制為256。

這是我使用的測試程序:

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

main()
{
  struct rlimit rlp;

  FILE *fp[10000];
  int i;

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

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

  getrlimit(RLIMIT_NOFILE, &rlp);
  printf("after %d %d\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; }
  }

}

輸出是:

before 256 -1
after 10000 -1
failed after 253

我不能要求使用我的應用程序的人在/ etc文件或其他內容中查找。 我需要應用程序自己完成它。

rlp.rlim_cur = 10000;

兩件事情。

1。 大聲笑。 顯然你在Mac OS X'stdio中發現了一個錯誤。 如果我修復你的程序/添加錯誤處理/ etc並用open()系統調用替換fopen(),我可以很容易地達到10000的限制(比我的10.6.3'OPEN_MAX限制10240低240 fds)

第2位。 RTFM: man setrlimit 最大打開文件的情況必須特別針對OPEN_MAX進行處理。

etresoft在蘋果討論板上找到答案:

這里的整個問題是你的printf()函數。 當您調用printf()時,您正在將內部數據結構初始化為特定大小。 然后,調用setrlimit()嘗試調整這些大小。 該函數失敗,因為您已經在printf()中使用了這些內部結構。 如果使用兩個rlimit結構(一個用於before,一個用於after),並且在調用setrlimit之后不打印它們,您會發現即使在命令行程序中也可以更改當前進程的限制。 最大值為10240。

出於某種原因(可能是二進制兼容性),您必須在包含<stdio.h>之前定義_DARWIN_UNLIMITED_STREAMS

#define _DARWIN_UNLIMITED_STREAMS

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

main()
{
  struct rlimit rlp;

  FILE *fp[10000];
  int i;

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

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

  getrlimit(RLIMIT_NOFILE, &rlp);
  printf("after %d %d\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; }
  }

}

版畫

before 256 -1
after 10000 -1
failed after 9997

此功能似乎已在Mac OS X 10.6中引入。

這可能是您的libc的一個嚴格限制。 某些版本的solaris具有類似的限制,因為它們將fd存儲為FILE結構中的unsigned char 如果你的libc也是這種情況,你可能無法做到你想要的。

據我所知,像setrlimit這樣的東西只影響你可以用open多少文件(fopen幾乎肯定是在open )。 因此,如果此限制在libc級別上,則需要備用解決方案。

當然,您總是不能使用fopen ,而是使用幾乎所有unix變體上的open系統調用。

缺點是你必須使用writeread而不是fwritefread ,它們不會做像緩沖這樣的事情(這些都是在你的libc中完成的,而不是由操作系統本身完成的)。 因此它最終可能成為性能瓶頸。

你能描述一下需要同時打開400個文件**的場景嗎? 我並不是說沒有必要的情況。 但是,如果您更清楚地描述您的用例,那么也許我們可以推薦更好的解決方案。

我知道這聽起來很愚蠢,但你真的需要同時打開400個文件嗎? 順便問一下,你是否以root身份運行此代碼?

Mac OS不允許我們像許多基於unix的操作系統那樣輕松更改限制。 我們必須創建兩個文件

/Library/LaunchDaemons/limit.maxfiles.plist /Library/LaunchDaemons/limit.maxproc.plist描述最大進程和最大文件限制。 文件的所有權需要更改為'root:wheel'

僅這一點並沒有解決問題,默認最新版本的mac OSX使用'csrutil',我們需要禁用它。 要禁用它,我們需要在恢復模式下重啟我們的mac,並從那里使用終端禁用csrutil。

現在,我們可以輕松地從終端本身輕松更改最大打開文件句柄限制(即使在正常啟動模式下)。

在以下鏈接中詳細解釋了該方法。 http://blog.dekstroza.io/ulimit-shenanigans-on-osx-el-capitan/

適用於OSX-elcapitan和OSX-Seirra。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM