Go语言如何监听FIFO文件输出并为等待过程设置超时
Go实现带超时的FIFO文件读取逻辑
实现思路:由于FIFO的读取操作默认是阻塞的,我们可以把阻塞读取逻辑放到独立goroutine中执行,通过通道传递读取结果,主协程同时监听读取结果和超时信号,即可实现和bash timeout命令等价的效果。
完整实现代码如下:
package main import ( "bufio" "fmt" "log" "os" "time" ) func main() { fifoFileName := "server_fifo" outputFileName := "server.url" timeout := 3000 * time.Second // 打开FIFO文件,若需要自动创建FIFO可先调用syscall.Mkfifo生成 file, err := os.OpenFile(fifoFileName, os.O_RDONLY, os.ModeNamedPipe) if err != nil { log.Fatal("Open named pipe file error:", err) } defer file.Close() reader := bufio.NewReader(file) // 定义通道传递读取结果,缓冲长度1避免goroutine泄露 resChan := make(chan error, 1) go func() { // 阻塞读取直到拿到换行 bs, err := reader.ReadBytes('\n') if err == nil { // 将读取内容写入server.url,和bash命令效果对齐 writeErr := os.WriteFile(outputFileName, bs, 0644) resChan <- writeErr return } resChan <- err }() select { case err := <-resChan: if err != nil { log.Fatalf("Process FIFO failed: %v", err) } fmt.Println("cockroach server started") case <-time.After(timeout): log.Fatalf("Wait FIFO output timeout after %v", timeout) } }
注意事项
- 若需要程序自动创建FIFO文件,不能直接通过os.OpenFile加os.O_CREATE参数生成,需要先调用
syscall.Mkfifo(fifoFileName, 0600)创建命名管道后再打开 - 超时触发时defer会自动关闭文件句柄,阻塞的读取操作会立即返回错误,不会出现goroutine泄露问题
- 可根据实际需求调整timeout常量的数值,示例中3000秒和你提供的bash命令配置一致
内容的提问来源于stack exchange,提问作者IsaIkari
相关产品推荐
相关产品推荐

