LINUX.ORG.RU

сокеты EMFILE: Too many open files. Что делать?


0

0

Есть сервер. К нему конектятся клиенты. И если приложение достигает максимума открытых файлов, то происходит следующее:

1. Аксептор (отдельный поток) прерывается из select-а
2. Вызывается accept - на каждое новое соеденение
3. accept возвращает EMFILE - и соответственно сокет не открывается.

Вроди всё ок, но с клиентами случаются нехорошие вещи: они начинают отваливатся по таймауту, а не сразу, как отработал accept с ошибкой.

Чего бы хотелось: чтоб в случае перегруженого сервера (открыто слишком много соеденений) - клиенты сразу получали ошибку, а не ждали по 1, 5 или даже 10 секунд.

Можно както этого добится?

ЗЫ. accept - блокирующий и находится в выделеном потоку, но остальные операции с сокетами неблокирующие. Если сделать accept, неблокирующим чтото изменится?


Есть подозрение, что запросы на соеденение становятся в очередь и по немногу выбираются сокеты и получают ошибку при accept-е.
Если это так, то есть ли способ сбросить очередь (не переоткрывая сокет)?

stpg
() автор топика

В man'е советовали всегда делать accept() неблокирующемся, так как после вызова select() (которые "скажет", что есть ожидающий сокет), может произойти ошибка и сокет будет удален из очереди и accept заблокируется.

>Есть подозрение, что запросы на соеденение становятся в очередь и по немногу выбираются сокеты

Зачем подозрение. Посмотрите исходики ядра. Во всяком случае google говорт, что для Линкса предлагался патч, реализующий требуемое вам поведение: http://www.linux.sgi.com/archives/netdev/2004-11/msg00573.html Мне сейчас лень смотреть исходники 2.6.2x , поэтому не могу сказать, применен ли данный патч.

mky ★★★★★
()
Ответ на: комментарий от mky

> В man'е советовали всегда делать accept() неблокирующемся

Ну в моём случае если поток заблокируется до следующего соеденения не так страшно - это отдельный поток. Но всё таки перевести на неблокирующий accept надо.

>>Есть подозрение, что запросы на соеденение становятся в очередь и по немногу выбираются сокеты

> Зачем подозрение. Посмотрите исходики ядра

В 2.6.17 этот патч применен - так, что это не решает моей проблемы. Постараюсь написать минимальный пример и на нем уже тестировать.

Спасибо за ответ

stpg
() автор топика
Ответ на: комментарий от stpg

Не знаю, поможет или нет, но как вариант считать количество использованных файловых дескрипторов и не дожидаться EMFILE, а на предпоследнем закрывать соединение сразу после accept(). Да это костыль, но программа будет работать так как нужно, причем независимо от версии ядра. ИМХО, не так важно, что будет одновременно обрабатываться 1020, а не 1021 коннект...

mky ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.