fork()后关闭侦听套接字

Sil*_*ler 5 c c++ sockets linux

Linux/UNIX系统上的通用服务器套接字模式是侦听套接字,接受连接,然后fork()处理连接.

所以,看来以后你accept()fork(),一旦你的孩子的过程中,你将会继承父进程的监听的文件描述符.我已经读过,此时,您需要从子进程中关闭侦听套接字文件描述符.

我的问题是,为什么?这只是减少监听套接字的引用计数吗?或者,操作系统不会将子进程本身用作路由传入连接的候选者?如果是后者,我有点困惑有两个原因:

(A)是什么告诉操作系统某个进程是接受某个文件描述符上的连接的候选者?这个过程是否已经调用了accept()?或者这个过程是否已经调用listen()

(B)如果这个过程已经调用了listen(),那么我们这里是不是有竞争条件?该怎么办:

  1. 父进程侦听套接字S.
  2. 传入连接转到父进程.
  3. 父进程分叉子进程,子进程有套接字S的副本
  4. 孩子能够呼叫之前close(S),第二个传入连接进入子进程.
  5. 子进程从不调用accept()(因为它不应该),因此传入的连接被丢弃

是什么阻止了上述情况的发生?更一般地说,为什么子进程会关闭侦听套接字?

Col*_*Two 7

Linux将挂起的连接排队.accept从父进程或子进程调用将轮询该队列.

不关闭子进程中的套接字是资源泄漏,但不是很多.父节点仍将获取所有传入连接,因为它是唯一一个调用的连接accept,但是如果父节点退出,则套接字仍然存在,因为它在子节点上打开,即使子节点从不使用它.