如何在命名管道中的EOF之后恢复读取

时间:2017-03-26 08:44:26

标签: go named-pipes

我正在编写一个打开命名管道进行读取的程序,然后处理写入此管道的所有行:

err = syscall.Mkfifo("/tmp/myfifo", 0666)
if err != nil {
    panic(err)
}

pipe, err := os.OpenFile("/tmp/myfifo", os.O_RDONLY, os.ModeNamedPipe)
if err != nil {
    panic(err)
}

reader := bufio.NewReader(pipe)
scanner := bufio.NewScanner(reader)

for scanner.Scan() {
    line := scanner.Text()
    process(line)
}

只要写入过程没有重启或出于其他原因发送EOF,这样就可以正常工作。发生这种情况时,循环终止(正如Scanner的规范所预期的那样。)

但是,我想保持管道开放以接受进一步的写入。我当然可以重新初始化扫描仪,但我相信这会产生竞争条件,当新进程开始写入管道时扫描程序可能没有准备就绪。

还有其他选择吗?我是否需要直接使用File类型?

1 个答案:

答案 0 :(得分:0)

来自bufio GoDoc

  

扫描...在扫描停止时返回false,或者到达输入的结尾或出错。

因此,您可以将文件保持打开并读取直至EOF,然后在文件更改时或定期间隔(即制作goroutine)时再次触发scanner.Scan(),并确保pipe变量不会超出范围,因此您可以再次引用它。

如果我理解您对竞争条件的正确理解,这不会成为一个问题(除非必须同步写入和读取操作)但是当重新初始化扫描仪时,它将最终返回到文件。