Как увеличиться, предел “максимума открывают файлы” в C на 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

Я не могу спросить людей, которые используют мое приложение для ввода по абсолютному адресу в / и т.д. файла или чего-то. Мне нужно приложение, чтобы сделать это отдельно.

6
задан acemtp 2 July 2010 в 14:53
поделиться

4 ответа

etresoft нашел ответ на дискуссионном форуме apple:

Вся проблема здесь в вашей функция printf(). Когда вы вызываете printf(), вы инициализируете внутренние структуры данных до определенного размеру. Затем вы вызываете функцию setrlimit(), чтобы чтобы попытаться изменить эти размеры. Эта функция не работает, потому что вы уже использовали эти внутренние структуры с помощью функции printf(). Если вы используете две структуры rlimit (одну для до и одна для после), и не печатать их только после вызова setrlimit, вы обнаружите, что можете изменять ограничения текущего процесса даже в программе командной строки программы. Максимальное значение равно 10240.

5
ответ дан 8 December 2019 в 18:32
поделиться

rlp.rlim_cur = 10000;

Две вещи.

1-й. РЖУ НЕ МОГУ. По-видимому, вы обнаружили ошибку в файле stdio Mac OS X. Если я исправлю вашу программу / добавлю обработку ошибок / и т. Д., А также заменю fopen () системным вызовом open (), я легко смогу достичь предела в 10000 (что на 240 fds ниже моего 10.6.3 'предела OPEN_MAX 10240)

2-й. RTFM: man setrlimit . Случай максимального количества открытых файлов должен рассматриваться специально в отношении OPEN_MAX.

5
ответ дан 8 December 2019 в 18:32
поделиться

Это может быть жестким ограничением вашей libc. Некоторые версии Solaris имеют подобное ограничение, потому что они хранят fd как unsigned char в FILE struct. Если это относится и к вашей libc, возможно, вы не сможете сделать то, что хотите.

Насколько я знаю, такие вещи как setrlimit влияют только на то, сколько файлов вы можете открыть с помощью open (fopen почти наверняка реализован в терминах open). Так что если это ограничение лежит на уровне libc, вам потребуется альтернативное решение.

Конечно, вы всегда можете не использовать fopen и вместо этого использовать системный вызов open, доступный практически в каждом варианте unix.

Недостатком является то, что вам придется использовать write и read вместо fwrite и fread, которые не делают таких вещей, как буферизация (это все делается в вашей libc, а не самой ОС). Так что в итоге это может стать узким местом в производительности.

Можете ли вы описать сценарий, в котором требуется открыть 400 файлов ** одновременно**? Я не говорю, что не существует случая, когда это необходимо. Но если вы более четко опишите ваш сценарий использования, то, возможно, мы сможем порекомендовать лучшее решение.

2
ответ дан 8 December 2019 в 18:32
поделиться

Я знаю, это звучит глупо, но вам действительно нужно одновременно открывать 400 файлов? Кстати, вы запускаете этот код как root?

0
ответ дан 8 December 2019 в 18:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: