【发布时间】:2015-11-30 22:10:37
【问题描述】:
Linux/UNIX 系统上常见的服务器套接字模式是侦听套接字,接受连接,然后fork() 处理连接。
所以,似乎在您accept() 和fork() 之后,一旦您进入子进程,您将继承父进程的侦听文件描述符。我已经读到此时,您需要从子进程中关闭侦听套接字文件描述符。
我的问题是,为什么?这仅仅是为了减少监听套接字的引用计数吗?还是这样子进程本身不会被操作系统用作路由传入连接的候选者?如果是后者,我有点困惑,原因有二:
(A) 什么告诉操作系统某个进程可以接受某个文件描述符上的连接?是不是进程调用了accept()?还是进程调用了listen()这一事实?
(B) 如果进程调用了listen(),我们这里不是有竞争条件吗?如果发生这种情况怎么办:
- 父进程监听socket S。
- 传入连接转到父进程。
- 父进程派生一个子进程,子进程拥有套接字 S 的副本
-
在子进程能够调用
close(S)之前,第二个传入连接转到子进程。 - 子进程从不调用
accept()(因为它不应该调用),因此传入的连接被丢弃
是什么阻止了上述情况的发生?更一般地说,为什么子进程要关闭监听套接字?
【问题讨论】: