【问题标题】:What happens when parent-child listen on the same port?当父子监听同一个端口时会发生什么?
【发布时间】:2012-02-26 08:20:27
【问题描述】:

我有一个父进程,当它启动时,它会启动一个线程,该线程创建一个 TCP 服务器实例,该实例侦听端口 X。此后,父进程开始分叉子进程(它们做一些事情并退出)。请注意,这些子进程从父进程继承 fd,因此最终会监听端口 X。

父程序有一个处理程序来处理端口 X 上的请求,但子进程没有这样的处理程序(它是一个 os.execv()-ed C++ 程序)

我知道子进程可以关闭所有fds,这样就不会出现上述情况。端口 X 上的传入请求会发生什么情况?它是如何处理的?

这是我目前观察到的... 父母中的 tcp 请求处理程序在收到请求时执行 commands.getstatusoutput(..)。大多数时候,它的行为符合预期(或我预期的方式) - 执行上述命令没有任何错误......但偶尔我得到

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

【问题讨论】:

标签: python sockets networking operating-system fork


【解决方案1】:

在操作系统级别,这应该没有任何问题。这本质上是预分叉服务器的工作方式:

  1. 在主线程中创建套接字
  2. 将套接字绑定到一个地址
  3. 调用listen() 使套接字进入监听模式——此时,任何连接请求都将被操作系统接受并排队
  4. fork 一堆孩子,每个孩子都继承打开的套接字
  5. 然后子进程处理每个调用accept(),这会阻塞直到有一个连接供它们处理。

如果孩子选择不在侦听套接字上调用 accept(),(因为您的 exec'ed 进程不会)那么该进程或仍在接受连接的进程不应该有任何问题.

我能看到的唯一复杂情况是套接字无法关闭——为了让操作系统真正关闭它,所有引用它的进程都必须调用它的 close(),从而将它的打开描述符倒数到零。

在您的情况下,如果该行为干扰了您的应用程序的其余部分,则最好关闭子进程中的侦听套接字——在您 fork 之后,但在您调用 exec 之前。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-17
    • 2019-02-20
    • 2014-03-06
    • 2019-09-13
    • 2017-03-28
    • 1970-01-01
    相关资源
    最近更新 更多