Что происходит, когда parent-child прослушивает один и тот же порт? - PullRequest
0 голосов
/ 03 февраля 2012

У меня есть родительский объект, который при запуске запускает поток, который создает экземпляр TCP-сервера, который прослушивает порт X. После этого родительский процесс начинает блокировать дочерние процессы (которые выполняют несколько действий и завершают работу).Обратите внимание, что эти дочерние процессы наследуют fds от родительского и, следовательно, в конечном итоге прослушивают порт X.

Родительская программа имеет обработчик для запросов, поступающих через порт X, но дочерний процесс не имеет такого обработчика (это os.execv () - ed C ++ program)

Я знаю, что дочерний процесс может закрыть все fds, и в этом случае описанная выше ситуация не возникнет.Что происходит с входящим запросом через порт X?Как это обрабатывается?

Вот что я наблюдал до сих пор ... Обработчик tcp-запроса в родительском элементе выполняет command.getstatusoutput (..), когда он получает запрос.В большинстве случаев он ведет себя как ожидалось (или так, как я ожидал) - выполнение вышеуказанной команды без каких-либо ошибок ... но иногда я получаю

File "/home/y/lib/python2.7/commands.py", line 61, in getstatusoutput
    sts = pipe.close()
IOError: [Errno 10] No child processes

1 Ответ

8 голосов
/ 03 февраля 2012

На уровне операционной системы с этим не должно быть никаких проблем. По сути, именно так работают предварительно разветвленные серверы:

  1. Создать сокет в главном потоке
  2. Свяжите сокет с адресом
  3. Вызовите listen (), чтобы перевести сокет в режим прослушивания - в этот момент ОС запрашивает любые запросы на подключение и ставит их в очередь
  4. Разветвляется куча детей, каждый из которых наследует открытый сокет
  5. Затем дочерний процесс обрабатывает каждый вызов accept (), который блокируется до тех пор, пока для них не будет установлено соединение.

Если ребенок решает не вызывать accept () на слушающем сокете, (как ваш exec'ed процесс не будет), тогда не должно быть никаких проблем для этого процесса или для тех, кто все еще принимает соединения .

Единственное осложнение, которое я вижу, состоит в том, что сокет не может быть закрыт - для того, чтобы операционная система фактически закрыла его, все процессы со ссылкой на него должны вызывать close () для него, приводя его открытый дескриптор обратного отсчета до нуля.

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

...