Получение событий в дочерних элементах

Я пишу TCP-сервер, используя libev. Я создаю сокет и разветвляюсь после listen(), затем запускаю наблюдатель чтения libev на прослушивающем сокете и получаю клиентские соединения в обратном вызове наблюдателя. Может ли быть ситуация, когда оба: дочерний и родительский (или два дочерних, если их больше одного) получили событие о том, что слушающий сокет стал доступным для чтения, и оба попытаются установить клиентское соединение accept(), в этом случае один из процессов заблокируется? Я написал тестовую программу, и кажется, что только один процесс получает событие готовности к чтению, но, может быть, я ошибаюсь? Где я могу прочитать о поведении системы в этом случае? Как ядро ​​распределяет нагрузку между процессами и решает, кто получит событие? Является ли это бэкэндом (выбор, epoll и т. д.) и/или специфичным для ОС?


person user1940679    schedule 01.01.2013    source источник


Ответы (1)


Весьма вероятно, что оба процесса получат от сокета индикацию готовности и в результате оба вызовут accept(). Это одна из причин, по которой вы всегда должны использовать неблокирующие файловые дескрипторы с API-интерфейсами, основанными на событиях, такими как socket(), poll(), epoll() или kqueue() (или libev, который обеспечивает абстракцию для одного или нескольких из них). Если вы используете неблокирующие сокеты, то один потомок получит успешный результат от accept(), а все остальные получат EAGAIN, проигнорируют его и вернутся в сон без причинения вреда.

person Celada    schedule 01.01.2013