我已经被这个问题困扰了几个小时:
我有一个主进程作为 TCP 服务器,主进程调用 Fork(),将其 net.Listener() 的 FD 传递给子进程。然后子进程可以使用 net.Filelistener() 来继承这个 FD。
我通过许多开源代码研究了这个问题,也做了一些实验。但不幸的是,这些解决方案目前都不能让我满意,因为它们不可移植,你还需要许多危险的低级工作。
如果有任何解决方案可以安全地将 net.Listener() 的 FD 传递给子进程,我很高兴知道。
我现在尝试过的:
环境值,不可移植,会导致许多 FD 混乱,不安全,因为可以从外部更改。
Dup FD & Clear
FD_CLOEXEC
然后 exec/fork,可移植但不受 Go API 支持,syscall.NoCloseOnExec()
提交给开发团队的更改被拒绝,因为他们希望保持系统调用干净。设置
SO_REUSEADDR
子进程可以立即监听端口,在此之前关闭父进程的监听器。失败,不可移植,Go API 不支持,也不安全。exec.Command.ExtraFiles()
,不知道如何从子进程获取继承的 FD,我需要一个配置文件来保存 FD 和名称吗?此解决方案也有一个错误,请阅读 exec 的文档以获取更多详细信息。
好的,我已经为这个问题编写了一个简单的测试用例(带有解决方案 4):
https://github.com/reckhou/go-fd-pass-test
还包括 2 个 OS X 和 Linux 上的可执行文件。我试过 Go 1.1 & Go 1.1.1 但这个问题仍然存在。