Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何传递net.Listener();FD到子进程安全吗?_Go_File Descriptor - Fatal编程技术网

Go 如何传递net.Listener();FD到子进程安全吗?

Go 如何传递net.Listener();FD到子进程安全吗?,go,file-descriptor,Go,File Descriptor,这个问题困扰了我好几个小时: 我有一个主进程作为TCP服务器,主进程调用Fork(),将其net.Listener()的FD传递给子进程。然后子进程可以使用net.Filelistener()继承此FD 我通过许多开源代码研究了这个问题,也做了一些实验。但不幸的是,这些解决方案目前都不能让我满意,因为它们不可移植,你还需要很多危险的低级工作 如果有任何解决方案可以安全地将net.Listener()的FD传递给子进程,我很乐意知道 我现在尝试的是: 环境值不可移植,将导致许多FD混乱,因为可以从

这个问题困扰了我好几个小时:

我有一个主进程作为TCP服务器,主进程调用Fork(),将其net.Listener()的FD传递给子进程。然后子进程可以使用net.Filelistener()继承此FD

我通过许多开源代码研究了这个问题,也做了一些实验。但不幸的是,这些解决方案目前都不能让我满意,因为它们不可移植,你还需要很多危险的低级工作

如果有任何解决方案可以安全地将net.Listener()的FD传递给子进程,我很乐意知道

我现在尝试的是:

  • 环境值不可移植,将导致许多FD混乱,因为可以从外部更改,因此不安全

  • Dup FD&Clear
    FD_CLOEXEC
    then exec/fork,可移植但不受Go API支持,提交给开发团队的
    syscall.NoCloseOnExec()
    更改被拒绝,因为他们希望保持系统调用干净

  • 设置
    SO\u REUSEADDR
    以便子进程可以立即侦听端口,在此之前关闭父进程的侦听器。失败,不可移植,Go API不支持,也不安全

  • exec.Command.ExtraFiles()
    ,不知道如何从子进程获取继承的FD,是否需要配置文件来保存FD&name?此解决方案还有一个bug,请阅读exec的文档以了解更多详细信息

  • 好了,伙计们,我已经为这个问题编写了一个简单的测试用例(使用解决方案4):


    在OS X和Linux上还包括2个可执行文件。我尝试了Go 1.1和Go 1.1.1,但这个问题仍然存在。

    最简单的方法是在exec.Cmd的ExtraFiles字段中传递侦听器

    家长的例子:

    var l *net.TCPListener
    cmd := exec.Command(...)
    f, err := l.File()
    cmd.ExtraFiles = []*os.File{f}
    
    儿童的例子:

    l, err := net.FileListener(os.NewFile(3, "listener"))
    

    您可能还希望对此进行泛化,并让子级接受PROGRAMNAME\u LISTENER\u FD作为环境变量。然后,父级将在启动子级之前将环境变量设置为3。

    我正在寻找相同的环境变量,以便在WINDOWS中侦听环回地址、读取数据并发送到exec命令

    任何建议,因为windows不支持文件描述符 在UNIX中,我们执行以下操作

    服务:=“:1200” tcpAddr,err:=net.ResolveTCPAddr(“tcp”,服务)

    cmd:=exec.Command(execname)

    cmd.ExtraFiles=[]*os.File{File}-->在unix it支持中/在windows中如何添加数据


    cmd.Start()

    您介意发布一些代码吗?特别是你想要避免的不安全的东西?这将有助于回答您的问题。我将稍后发布我的解决方案,但不是现在,因为它可能会设置限制。我认为
    []*os.File{l}
    应该是
    []*os.File{f}
    。使用环境变量不是一个好主意,因为可能正在运行多个FD。稍后我将测试此解决方案。另一个问题是如何从子进程继承FD?您没有显示
    3,“侦听器”
    是如何出现的。事实上,这一部分对于可扩展服务非常重要。此解决方案还有一个bug:请阅读上面的注释
    ExtraFiles[]*os.File
    。我已经测试了此代码,发现它在os X和centOS上都不起作用。对此很抱歉,但目前看来只有FD_CLOEXEC在工作。我在golang.org上看到没有实现TCPListen和TCConn,在Windows中有任何建议吗
    listener, err := net.ListenTCP("tcp",tcpAddr)
    if err != nil {
        return "", err
    }
    
    defer listener.Close()
    file, err := listener.File()   --> unix supports file descriptor / how about in windows ??
    if err != nil {  
        return "", err
    }