Передача файлов-дескрипторов между процессами асинхронно - PullRequest
0 голосов
/ 13 декабря 2011

Я внедряю веб-сервер, на котором мне нужно, чтобы родительский процесс делал следующее:

  • fork() новые рабочие процессы (пул) в начале.
  • Цикл навсегда, прослушивание входящих запросов (через сокетную связь).
  • Помещение дескриптора сокета (возвращаемого функцией accept()) в очередь.

и рабочий процесс выполнитследующее:

  • Однажды созданный цикл постоянно просматривает очередь для любых переданных дескрипторов сокетов.
  • Если он принимает дескриптор сокета, он обрабатывает запрос и соответственно обслуживает клиента.

После осмотра и поиска в Интернете я обнаружил, что могу послать файловый дескриптор между различными процессами через UNIX Domain Socket или Pipes.Но, к сожалению, я могу сделать это только синхронно!(Я могу отправить по одному fd за раз и не могу поместить его в очередь ожидания)

Итак, мой вопрос:

  • Как я могу сделать родительский процесспомещает дескриптор сокета в очередь ожидания, так что запрос ожидает, пока один из рабочих процессов не завершит предыдущий запрос?

Ответы [ 2 ]

2 голосов
/ 13 декабря 2011

Файловые дескрипторы являются целыми числами.Они используются для индексации в таблице процессов файловой информации, поддерживаемой ядром.Вы не можете ожидать, что дескриптор файла будет «переносимым» к другим процессам.

Это работает (в некоторой степени), если вы создаете файлы до , вызывая fork(), так как таблица дескрипторов файловявляется частью процесса и, следовательно, clone() d при создании дочернего элемента.Для файловых дескрипторов, размещенных после разделения процессов, например, при использовании accept() для получения нового сокета, вы не можете сделать это.

UPDATE : кажется, есть способ, используя sendmsg() с сокетами AF_UNIX, см. здесь для деталей, как упомянуто в этом вопросе .Я не знал этого, звучит немного «волшебно», но, видимо, это хорошо зарекомендовавший себя механизм, так почему бы не пойти дальше и реализовать это.

1 голос
/ 13 декабря 2011
  1. поместить fd во внутреннюю очередь (без блокировки, если хотите, но, вероятно, не обязательно)
  2. имеет поток в родительском процессе, который просто читает fd из внутренней очереди и отправляет его по каналу
  3. все дочерние процессы наследуют другой конец канала и конкурируют за чтение следующего fd , когда они завершают свою текущую работу
...