Сделать select () взломать без записи в файл desc? - PullRequest
4 голосов
/ 07 февраля 2011

В моем приложении есть эта нить, которая контролирует набор клиентских сокетов. Я использую select() для блокировки до тех пор, пока клиент не сделает запрос, чтобы я мог эффективно обрабатывать его без увеличения числа потоков.

Теперь проблема в том, что когда я добавляю нового клиента в список клиентов, мне приходится ждать, пока тайм-аут select() (установленный на 10 секунд) фактически добавит новый сокет к прослушиваемым сокетам.

Так что я бы хотел select() взломать до тайм-аута, чтобы можно было немедленно прослушать клиента.

У меня уже есть решение этой проблемы: создайте фиктивную пару сокетов, которую я всегда включаю в список прослушиваемых сокетов, и в которую я пишу, чтобы сделать select() трещину, но я надеюсь, что есть лучшее решение.

Редактировать : У меня нет доступа к eventfd(), потому что GLibc, который я использую, слишком старый (и у меня нет возможности его обновить). Поэтому мне, возможно, придется использовать fifo или сокет.

Вы знаете кого-нибудь?

Спасибо!

Ответы [ 4 ]

7 голосов
/ 07 февраля 2011

Обычный способ пробуждения цикла выбора состоит в добавлении конца чтения пары pipe() fd в набор просмотра выбора.Когда вам нужно активировать цикл выбора, запишите несколько фиктивных данных в конец записи файлового дескриптора.

Обратите внимание, что в Linux вы также можете рассмотреть возможность использования eventfd()вместо pipe() - он может быть несколько более эффективным (хотя и менее переносимым).

Вы также можете обрабатывать сокет прослушивания в цикле выбора вместо передачи его другому потоку.- это неявно разбудит цикл выбора, когда придет новый клиент.

3 голосов
/ 07 февраля 2011

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

0 голосов
/ 06 ноября 2015

Вы можете использовать WSAEventSelect , чтобы связать оконный сокет с HEVENT и ждать, а затем связать с сокетом HEVENT с другими дескрипторами, используя WaitForMultipleObjects .

0 голосов
/ 07 февраля 2011

Вы можете подать сигнал для принудительного вызова EINTR из select (), но обработка сигнала в многопоточных программах является черной магией, а socketpair () проще и надежнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...