Linux Go管道写入端被关闭,为什么?
我只是读了一些Go代码,它可以做以下几行:Linux Go管道写入端被关闭,为什么?,linux,go,Linux,Go,我只是读了一些Go代码,它可以做以下几行: type someType struct { ... ... rpipe io.ReadCloser wpipe io.WriteCloser } var inst someType inst.rpipe, inst.wpipe, _ := os.Pipe() cmd := exec.Command("some_binary", args...) cmd.Stdout = inst.wpipe c
type someType struct {
...
...
rpipe io.ReadCloser
wpipe io.WriteCloser
}
var inst someType
inst.rpipe, inst.wpipe, _ := os.Pipe()
cmd := exec.Command("some_binary", args...)
cmd.Stdout = inst.wpipe
cmd.Stderr = inst.wpipe
if err := cmd.Start(); err != nil {
....
}
inst.wpipe.Close()
inst.wpipe = nil
某些二进制文件是一个长期运行的过程
为什么inst.wpipe
关闭并设置为零?如果它不关闭会发生什么?关闭仪表管道是否常见/必要
是dup2(pipe_fd[1],1)
cmd.Stdout=inst.wpipe的C类似物;inst.wpipe.Close()
该代码是希望读取其他程序生成的输出的典型程序。该函数返回一对连接的
os.File
实体(或者,如果出现不应简单忽略的错误,则返回),其中第二个(w
或wpipe
)实体上的写入显示为第一个(r
/rpipe
)实体上的可读字节。但这是你第一个问题一半答案的关键,读者怎么知道所有作家都写完了
为了使读卡器获得EOF指示,所有具有或曾经访问管道写入端的写入器都必须调用close
操作。通过将管道的写端传递给以cmd.start()
开头的程序,我们允许该命令访问管道的写端。当该命令关闭该管道时,具有访问权限的实体之一已关闭该管道。但另一个具有访问权限的实体尚未关闭它:我们拥有写访问权限
要查看EOF,则必须使用wpipe.close()
关闭对wpipe
的访问。因此,答案是:
inst.wpipe
关闭并设置为零nil
部分可能有或可能没有任何功能;您应该检查代码的其余部分,以确定它是否存在
dup2(pipe_fd[1],1)
cmd.Stdout=inst.wpipe的C类似物;inst.wpipe.Close()?dup2
级别降低,而cmd.Stdout
级别更高(独立于操作系统)。cmd.Start()
的POSIX实现在调用fork
(或类似的东西)之后,将调用dup2
(或类似的东西)。inst.wipe.Close()
的POSIX等价物是Close(wfd)
其中wfd
是wpipe
中的POSIX文件号
在没有任何更高级别包装的C代码中,我们会有如下内容:
intfds[2];
如果(管道(fds)<0)。。。处理错误案例。。。
pid=fork();
开关(pid){
案例1:…处理错误。。。
案例0:/*儿童*/
如果(dup2(fds[1],1)<0 | | dup2(fds[1],2)<0)…处理错误。。。
如果(execve(prog,args,env)<0)…处理错误。。。
/*未到达*/
默认值:/*父级*/
如果(关闭(fds[1])<0)。。。
…从fds[0]读取。。。
}
(虽然如果我们足够仔细地检查
close
中的错误,我们可能应该足够仔细地检查管道
系统调用是否返回了描述符0和1,或1和2,或2和3,但在这里,我们可能会通过确保0、1和2至少对/dev/null
打开来处理此问题。).哦,对不起,这是一个输入错误。让我来修复它。stdout和stderr都是,并设置为wpipe。