На компьютере только один процесс может прослушивать определенный номер порта. Например, если процесс Apache прослушивает порт 80, никакое другое приложение также не может прослушивать порт 80.
Apache обычно предварительно разветвляет несколько процессов, только один из них прослушивает порт 80. Задача этого процесса - передать обработку для любого соединения одному из пула других процессов Apache так же быстро и эффективно, как и он. может.
Каждое из множества одновременных подключений к порту 80 отличается своим IP-адресом источника и номером порта TCP источника (который клиентский компьютер выбирает случайным образом из неиспользуемого набора).
(Edit)
Я был почти уверен, что веб-серверы прослушивают один процесс (или поток), который принимает входящие соединения и передает соответствующие файловые дескрипторы рабочим процессам (или потокам). EJP сообщает, что это не так.
Кажется, что в Apache есть несколько различных модулей многопроцессорной обработки , которые влияют на то, как он распределяет нагрузку по ответу на несколько одновременных запросов. Например: MPM Prefork и MPM Worker
Джефф Позканер написал обзор дизайна HTTP-сервера, который мне показался интересным:
Основная операция веб-сервера - принять запрос и отправить ответ. Первые веб-серверы, вероятно, были написаны именно для этого. Их пользователи, несомненно, очень быстро заметили, что, пока сервер отправляет ответ кому-то еще, они не могут обслуживать свои собственные запросы. Там были бы длинные раздражающие паузы.
Второе поколение веб-серверов решило эту проблему, отбрасывая дочерний процесс для каждого запроса. ...
Небольшой вариант сервера этого типа использует «облегченные процессы» или «потоки» вместо полноценных процессов Unix. ...
Третье поколение серверов называется «предварительная разветвленность». Вместо запуска нового подпроцесса для каждого запроса у них есть пул подпроцессов, которые они хранят и используют повторно. ...
Четвертое поколение. Только один процесс. Нет непереносимых потоков / LWP. Одновременно отправляет несколько файлов, используя неблокирующий ввод / вывод, вызывая select () / poll () / kqueue (), чтобы узнать, какие из них готовы для получения дополнительных данных. ...