Хитрость в том, что он использует неблокирующий ввод-вывод во втором процессе.Для получения дополнительной информации о том, чем руководствовались неблокирующие серверы ввода-вывода, я предлагаю прочитать проблему c10k на веб-сайте.Превосходно.
В любом случае, второй процесс зарегистрирует ядро в своем интересе к читаемым событиям , доступным для записи событиям и событиям ошибок снеблокирующий интерфейс ввода-вывода: select(2)
, poll(2)
, epoll(4)
или аналогичный.select(2)
проще всего говорить, так что поехали.Во-первых, все сокеты открываются с помощью SOCK_NONBLOCK
, чтобы убедиться, что операции с сокетом не будут блокироваться.Во-вторых, есть цикл управления, который ожидает активности на клиентских сокетах:
fd_set *f
FD_CLR(f)
foreach client socket
FD_SET(socket, f)
n_ready_to_read = select(max(socketvalue), f, NULL, f, 0)
for (i=0; i<max(socketvalue) && n_ready_to_read; n_ready_to_read--, i++)
if FD_ISSET(i, f)
handle_input_from_client(i)
}
Это всего лишь набросок того, как процесс обнаруживает, когда клиент отправил данные вместе и сокет выиграл 'Блок t при чтении .Так что read(2)
вызов на сокете не будет блокироваться.Конечно, поскольку один сервер одновременно выполняет запись и для многих клиентов, ему необходимо отслеживать сокеты, в которые он пишет, и отправлять им данные, когда они готовы принимать вызовы write(2)
, и аналогичные для обработки ошибок..
Есть лучший, более полный пример, например, select_tut(2)
.
select(2)
в значительной степени заменен в более новых системах, поскольку при создании списка проверяемых fds были значительные издержки,fd_set
реализован как 1024-битное битовое поле в Linux, и по причинам ABI никогда не может выйти за рамки этого, и поскольку нет хорошего способа сообщить ядру, что вы заинтересованы только в разреженном подмножествеиз этого списка, он должен проверять с 0- каждый раз , даже если в массиве не установлено много fds.
Итак, он был заменен механизмами, которые позволяют добавлять и удалять определенныефайловые дескрипторы из долгоживущего набора, которые допускают инициируемое фронтом и триггерное уведомление о «готовности», и не выполняют глупый поиск по large массивы фиксированного размера, чтобы найти интересующие вас файловые дескрипторы.
Библиотека libevent предоставляет замечательный уровень абстракции для этого процесса, который автоматически выбирает лучший доступный интерфейс на самых разных платформах и позволяет программистам сосредоточиться на коде, специфичном для их сервера.