我正在实现一个web服务器,我需要使父进程做以下事情:
-
fork()
开始时新的工作进程(一个池)。 - 永远循环,监听传入请求(通过套接字通信)。
- 将套接字描述符(由
accept()
函数返回)放入队列
和工作进程将执行以下操作:
- 一旦创建,循环永远观察队列中传入的套接字描述符。
- 如果他接受套接字描述符,他处理请求并相应地为客户端服务。
经过查看和搜索互联网,我发现我可以通过UNIX Domain Socket
或Pipes
在不同进程之间发送文件描述符。但不幸的是,我只能同步地做到这一点!(我可以一次发送一个fd
,我不能把它放在等待队列中)
那么,我的问题是:
- 我如何使父进程将套接字描述符放入等待队列,以便请求挂起,直到其中一个工作进程完成前一个请求?
文件描述符只是整数。它们用于索引到每个进程的文件信息表,由内核维护。你不能指望一个文件描述符可以"移植"到其他进程。
如果在调用fork()
之前创建文件,它(在某种程度上)是有效的,因为文件描述符表是进程的一部分,因此在创建子进程时是clone()
d。对于在进程分裂之后分配的文件描述符,例如当使用accept()
获取新的套接字时,您不能这样做。
UPDATE:似乎有一种方法,使用sendmsg()
与AF_UNIX套接字,请参阅此处了解本问题中提到的详细信息。我不知道这一点,听起来有点"神奇",但显然这是一个行之有效的机制,所以为什么不继续实施呢?
- 将fd放在一个内部队列中(如果你想,可以不加锁,但可能不是必需的)
- 在父进程中有一个线程,它只是从内部队列中读取一个fd,并通过管道 发送它
- 所有子进程继承管道的另一端,并在完成当前任务时竞争读取下一个fd