Intereting Posts
Runtime.getRuntime () не обеспечивает вывод на сервере Создание быстрых клавиш Mac (например, Cmd-C) для работы с linux Как программно изменить дату создания, изменения, доступа к файлу? redirect на небезопасный контент (http) из безопасного (https) Перенаправление stdout / stderr в Windows Невозможно получить расширения git, чтобы подтолкнуть что-то к задачам SSH для github Как обнаружить неактивного пользователя Не удается найти папку .android в ubuntu GitWeb очень медленный под Apache в Windows, используя MSysgit Perl intrepretor Удостоверьтесь, что переменная int имеет длину 2 цифры, иначе добавьте 0 впереди, чтобы сделать ее длиной 2 цифры Как искать файлы в обозревателе файлов Windows с указанным именем расширения? htaccess перенаправляет root в подкаталог, но разрешает функции index.php в корне Рекомендации по изучению Perl? Запуск нового сеанса tmux и его отсоединение, все внутри сценария оболочки Bash: подождите, пока загрузка процессора не станет ниже порога

закрыть на разъеме, не отпуская дескриптор файла

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

Теперь я понимаю, что это из-за ulimit, я не понимаю, почему я нажимаю его, если я вызываю close () после каждого синхронного цикла accept / read / send?

Я подтверждаю, что дескрипторы на самом деле существуют, запустив часы с lsof:

  ctsvr 9733 mike 1017u sock 0,7 0t0 3323579 не может идентифицировать протокол
 ctsvr 9733 mike 1018u sock 0,7 0t0 3323581 не может идентифицировать протокол
 ... 

И, конечно же, их около 1000. Более того, при проверке с netstat я вижу, что не существует висячих состояний TCP (нет WAIT или STOPPED или что-то еще).

Если я просто делаю одиночный connect / send / recv от клиента, я замечаю, что сокет остается в списке lsof; так что это даже не проблема с нагрузкой.

Сервер работает на 64-битной машине Ubuntu Linux.

Есть предположения?

Поэтому, используя strace (спасибо Gearoid), о котором я понятия не имею, как я жил, я заметил, что фактически закрывал дескрипторы.

Однако. И ради потомства я обнажил свою глупую ошибку:

 Socket::Socket() : impl(new Impl) { impl->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); .... } Socket::ptr_t Socket::accept() { auto r = ::accept(impl->fd, NULL, NULL); ... ptr_t s(new Socket); s->impl->fd = r; return s; } 

Как вы можете видеть, мой конструктор сразу выделил сокет, а затем я заменил дескриптор на тот, который был возвращен accept-create утечкой. Я переустановил код принятия из автономного classа Acceptor в class Socket, не изменяя его.

Используя strace, я мог легко видеть, что socket () запускается каждый раз, что приводит к моменту моей лампочки.

Спасибо всем за помощь!

Вы когда-нибудь вызывали perror () после закрытия ()? Я думаю, что возвращенная строка даст вам некоторую помощь;

Скорее всего, вы recv() команду recv() или send() . Подумайте о настройке таймаута с помощью setsockopt .

Я заметил аналогичный вывод на lsof, когда сокет был закрыт на другом конце, но мой stream удерживал сокет открытым, зависающим в команде recv() ожидающей данных.