Пересечение лимита обработчика файлов 256 - PullRequest
2 голосов
/ 23 ноября 2008

Мой код открывает более 256 файловых дескрипторов, поэтому, когда я запускаю его на компьютерах Solaris, я получаю сообщение об ошибке «Превышение лимита обработчиков файлов».

У меня есть два вопроса по этому поводу

1) Является ли это ограничение только для 32-разрядных программ или 64-разрядных программ также страдают от него. Я погуглил об этом и узнал, что 64-битные программы не имеют этого ограничения. (http://developers.sun.com/solaris/articles/stdio_256.html) Но я построил 64-битный статический объект, и когда я использую это, он дает ошибку. Что на самом деле означает 64-битное программное обеспечение?

2) Как указано в приведенной выше ссылке, я использовал ulimit для увеличения лимита обработчиков файлов (во время выполнения я имею в виду непосредственно перед запуском команды), экспортировал библиотеку extendedFile, и я не получил никакой ошибки. в случае Linux?

Спасибо Д. Л. Кумар

Ответы [ 5 ]

3 голосов
/ 23 ноября 2008

Я сталкивался с этим раньше. Насколько я могу судить, это на самом деле ошибка в libc от Solaris, где они используют 8-битный целочисленный тип без знака для хранения fd в структуре FILE. Очевидно, они не меняли это очень быстро во имя обратной совместимости (в случае, если программа по какой-то причине зависела от деталей реализации структуры FILE). Это должно НЕ быть проблемой для Linux или любого другого не Solaris * nix. В приведенной вами статье предложены разумные обходные пути, поэтому вы должны их использовать.

Что касается «что такое 64-битный исполняемый файл», то это просто двоичный файл, который был скомпилирован для набора 64-битных команд. Некоторые архитектуры поддерживают, а некоторые нет. (Например, операционные системы x86-64 обычно допускают 32-битные процессы для обратной совместимости).

1 голос
/ 23 ноября 2008

В Solaris вы создаете 64-битные программы, используя либо:

cc -xarch=v9 ...

Или:

gcc -m64 ...

Как сказал Эван, фундаментальная проблема для 32-битного Solaris - обратная двоичная совместимость и 8-битное целое число, используемое для хранения fd.

Я только что попробовал этот код на Solaris 10 для SPARC:

#include <stdio.h>

int main(void)
{
    size_t i;
    for (i = 0; i < 300; i++)
    {
        FILE *fp = fopen("/dev/null", "a");
        if (fp == 0)
        {
            printf("Failed on %zu\n", i);
            return(1);
        }
    }
    printf("Succeeded to %zu\n", i);
    return(0);
}

Составлено как:

cc -xarch=v9 -o xxx xxx.c

И это дало мне «провал на 253». (Это тестовый код: я знаю, что он выбрасывает 252 указателя.) Это поддерживает ваше утверждение о том, что простая 64-битная сборка. Тем не менее, есть еще один фактор - ограниченность ресурсов.

$ ulimit -n
256
$

Итак, увеличение лимита по умолчанию с:

$ ulimit -n 400
$ ulimit -n
400
$ ./xxx
Succeeded to 300
$

Попробуй это ...

1 голос
/ 23 ноября 2008

Чтобы проверить, является ли объектный файл (исполняемый) 64-битным, используйте команду file (по крайней мере, в Linux).

Например:

$ file `which ls`
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), stripped

$ file my-32bit-exe
my-32bit-exe: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), corrupted section header size

(не обращайте внимания на «размер заголовка поврежденного раздела» - exe был вручную искажен для уменьшения размера файла).

ulimit может использоваться в Linux (см. ulimit (1) и ulimit (3) ).

0 голосов
/ 24 ноября 2008

Наконец-то я получил решение. Я сделал два изменения в своем коде, чтобы он работал

1) как предложено выше njsf

2) Открытие файла с флагом "F", следующим образом FILE * fp = fopen ("/ dev / null", "wF");

Большое спасибо. Д. Л. Кумар

0 голосов
/ 23 ноября 2008

Как упоминал Эван Теран, у Solaris libc есть «странное» ограничение для FILE, которое может обрабатывать только файловые дескрипторы менее 256.

Это независимо от предела, который вы можете установить с помощью ulimit. Вы можете установить этот лимит из вашей программы с помощью:

#include <sys/resource.h>

struct rlimit rl;
getrlimit(RLIMIT_NOFILE,&rl);
rl.rlim_cur = 1024; /* change it to 1024 - note has to be < than rl.rlim_max */
setrlimit(RLIMIT_NOFILE,&rl);

Теперь я бы также прекратил использовать FILE * и использовал open вместо fopen и т. Д. И т. Д. Для случаев, когда вам действительно нужно использовать FILE *, в нескольких проектах, над которыми я работал, в начале программы несколько файловых дескрипторов были «зарезервированы» с помощью вызова сокета, и у нас была небольшая библиотека для получения FILE * с использованием они закрывают один из сокетов и сразу после этого делают fopen, который будет использовать только что закрытый fd. Конечно, нужно также закрыть FILE * специальной функцией, которая будет fclose, а затем сразу получить fd с помощью сокета; -)

...