Я пишу TCP-сервер, используя libev. Я создаю сокет и разветвляюсь после listen(), затем запускаю наблюдатель чтения libev на прослушивающем сокете и получаю клиентские соединения в обратном вызове наблюдателя. Может ли быть ситуация, когда оба: дочерний и родительский (или два дочерних, если их больше одного) получили событие о том, что слушающий сокет стал доступным для чтения, и оба попытаются установить клиентское соединение accept(), в этом случае один из процессов заблокируется? Я написал тестовую программу, и кажется, что только один процесс получает событие готовности к чтению, но, может быть, я ошибаюсь? Где я могу прочитать о поведении системы в этом случае? Как ядро распределяет нагрузку между процессами и решает, кто получит событие? Является ли это бэкэндом (выбор, epoll и т. д.) и/или специфичным для ОС?
Получение событий в дочерних элементах
Ответы (1)
Весьма вероятно, что оба процесса получат от сокета индикацию готовности и в результате оба вызовут accept()
. Это одна из причин, по которой вы всегда должны использовать неблокирующие файловые дескрипторы с API-интерфейсами, основанными на событиях, такими как socket()
, poll()
, epoll()
или kqueue()
(или libev, который обеспечивает абстракцию для одного или нескольких из них). Если вы используете неблокирующие сокеты, то один потомок получит успешный результат от accept()
, а все остальные получат EAGAIN
, проигнорируют его и вернутся в сон без причинения вреда.
person
Celada
schedule
01.01.2013