我正在尝试使用Go在Linux上读取命名管道。通常,File.Read函数会阻塞,直到管道上有可用数据为止,但是可以使用相对较新的File.SetReadDeadline函数在Read上设置“超时”。
但是,我发现此超时仅在第一次读取时发生。如果我运行以下代码,则消息“超时,开始新的读取”仅打印一次,并且管道。Read调用在下一次循环中将阻塞。 (仍然有效,如果我将数据发送到管道,则会收到“已收到”消息。)
func Read(pipe *os.File) error {
for {
pipe.SetDeadline(time.Now().Add(5000 * time.Millisecond))
buff := make([]byte, 1024*64)
s, err := pipe.Read(buff)
if err == nil {
log.Printf("Received bytes of length %d", s)
} else if os.IsTimeout(err) {
log.Println("Timed out, starting new read")
} else {
log.Printf("Pipe error %s", err)
return err
}
}
}
在我的研究中,似乎我可能需要重置底层的轮询上下文(无论这意味着什么。)是否有某种方法可以使这项工作奏效,或者仅仅是一个Go bug?