Python 父服务器分叉需要及时退出

Python 父服务器分叉需要及时退出,python,fork,exit,Python,Fork,Exit,我有一个服务器草稿,它在新的客户端连接之后派生新的子服务器。然后根据客户端的命令,子服务器在函数处理程序(连接)内执行一些工作 同时,我想停止父服务器,在此之前让父服务器等待所有工作的子服务器 问题是Ctrl+C键盘中断选项的信号功能应该放在哪里。 signal.signal(signal.SIGINT,信号处理器) 问题是Ctrl+C键盘中断选项的信号功能应该放在哪里。signal.signal(signal.SIGINT,信号处理器) 只要是在定义信号处理程序之后和调用接受之前,您就可以在任

我有一个服务器草稿,它在新的客户端连接之后派生新的子服务器。然后根据客户端的命令,子服务器在函数处理程序(连接)内执行一些工作

同时,我想停止父服务器,在此之前让父服务器等待所有工作的子服务器

问题是
Ctrl+C
键盘中断选项的信号功能应该放在哪里。 signal.signal(signal.SIGINT,信号处理器)

问题是Ctrl+C键盘中断选项的信号功能应该放在哪里。signal.signal(signal.SIGINT,信号处理器)

只要是在定义
信号处理程序
之后和调用
接受
之前,您就可以在任何地方使用它

我不确定那个信号处理器是不是你想要的。在大多数平台上,您实际执行的操作会立即退出,就像您要求的那样,导致子项被重新分配到
init
launch
或类似位置。但你要等所有的孩子。因此,您不能调用
exit

在POSIX中,不允许在信号处理器内调用
waitpid
。Python信号处理程序不是真正的信号处理程序,所以这可能与此无关,但我认为这一事实在任何地方都不能保证。如果您想冒险,可以尝试在调用
exit
之前,在
signal\u handler
中等待所有的孩子,看看它是否在您的平台上工作

但是,标准的POSIX方法是让信号处理程序设置一些全局标志并返回。然后,主程序将从
accept
或它正在等待的任何其他阻塞调用中唤醒,并出现
EINTR
错误,此时它可以检查标志(如果为真),等待子程序并退出的时间;否则,返回循环并再次接受

但无论如何,这一切都不是必要的。默认的SIGINT处理程序应该只引发一个
键盘中断
,这意味着如果不安装自定义信号处理程序,那么真正需要做的就是捕获该异常。换句话说,只需将最后一行替换为:

try:
    accept()
except KeyboardInterrupt: # or maybe BaseException
    # wait for children, blocking instead of WNOHANG of course
    sys.exit(0)

修复缩进将非常有帮助,因此它既可读又可运行。事实上,我可以猜到它在做什么,但如果我不必猜的话,那就更好了。另外,您使用
fork
而不是
threading
,有什么特别的原因吗?有很多很好的理由(例如,如果孩子们不像典型的服务器处理程序那样主要在I/O上等待,但有很多CPU工作要做……或者如果你想分离它们,这样你就可以关闭接收器,但让现有的客户机运行……等等),但我很好奇你的理由是什么。还有最后一点需要注意的是:TCP服务器通常希望在调用
bind
之前调用
conn.setsockopt(socket.solu_socket,socket.SO_REUSEADDR,1)
。(有关古代常见问题解答和更多详细信息,请参阅。)我需要在这里使用fork…线程不是必须使用的…我想等待所有正在工作的子服务器…正如我在上面所说的“我想停止父服务器,在此之前让父服务器等待所有正在工作的子服务器。”我尝试将signal.signal(signal.SIGINT,signal\u handler)“放在任何位置”…它只是按正确的方式退出,并且父级不等待子级…因此会出现错误。@NatashaAlmazova:是的,但这不是因为您将代码放在哪里,而是因为您的信号处理程序通过调用
sys.exit
立即退出。在大多数*nix平台上,这会完全按照您的要求执行,导致子级被重新租入
init
launchd
或类似版本。这就是为什么我说“我不确定信号处理程序是否真的是你想要的。”@NatashaAlmazova:你可以编写一个信号处理程序,它会导致
accept
异常失败,然后你可以捕获并收获你的孩子。但实际上,你不需要;默认处理程序将只引发一个
键盘中断
异常。哦,所以我需要重新做一些事情…我需要找到活动子项的数量,然后一旦它为零,然后允许退出signal.signal(signal.SIGINT,signal\u处理程序)?可能吗。。。。。对不起,这里太晚了,我走得很慢。。。
try:
    accept()
except KeyboardInterrupt: # or maybe BaseException
    # wait for children, blocking instead of WNOHANG of course
    sys.exit(0)