当阅读器断开连接时,命名管道 (FIFO) 数据会去哪里?
Posted
技术标签:
【中文标题】当阅读器断开连接时,命名管道 (FIFO) 数据会去哪里?【英文标题】:Where does named pipe (FIFO) data go when reader disconnects? 【发布时间】:2016-08-06 12:24:47 【问题描述】:假设我有一个producer.go
和consumer.go
。 consumer.go
从 UNIX 命名管道读取,生产者写入命名管道。
正如预期的那样,如果您只启动一个生产者或消费者程序,它会挂起,因为管道的另一端没有读取器或写入器。
现在,如果我启动这两个程序,然后立即从消费者那里按 CTRL-C,生产者继续向管道发送数据,据我所知,该数据的大小没有限制(我发送了 80MB )
如果我再次启动消费者程序(当生产者仍在运行时),它会开始从命名管道中提取数据,而不是在消费者程序未运行时我“错过”的数据。
我的问题是:当命名管道的读取器断开连接时,发送到命名管道的数据会发生什么情况?
这是我的consumer.go
和producer.go
程序:
consumer.go
package main
import (
"io"
"io/ioutil"
"log"
"os"
"syscall"
)
func main()
syscall.Mkfifo("fifo0", 0777)
fp, err := os.OpenFile("fifo0", os.O_RDONLY, 0777)
if err != nil
log.Fatalf("Could not open fifo0: %s", err)
tee := io.TeeReader(fp, os.Stdout)
ioutil.ReadAll(tee)
生产者.go
package main
import (
"fmt"
"io"
"log"
"os"
"strings"
"time"
)
func main()
dots := strings.Repeat(".", 990)
fifo, err := os.OpenFile("fifo0", os.O_WRONLY, 0777)
if err != nil
log.Fatalf("Could not open fifo0: %s", err)
defer fifo.Close()
w := io.MultiWriter(os.Stdout, fifo)
for i := 0; i < 8000; i++
fmt.Fprintf(w, "%010d%s\n", i, dots)
time.Sleep(time.Millisecond * 10)
【问题讨论】:
你没有检查写入管道的错误 当我检查错误时,似乎在没有接收器但没有阻塞时确实显示错误,很高兴知道。 【参考方案1】:FIFO 至少需要一个源和一个目标,才能将数据传输到任何地方。一个读者独自等待从某人那里拉取,而一个作家独自等待发送给某人。这样一来,一对一的管道就没有缝隙了。
因此,如果您仍在尝试从断开连接或不存在的管道的一端读取或写入,答案是数据无处可去;管道被“阻塞”并且不能保存自己的数据。所以这取决于你的代码如何处理这种情况。
在producer.go
中,即使不再有连接,循环也会继续运行。因为Fprintf
或MultiWriter
不会因任何原因引发代码停止错误。在这种情况下,您可以在循环中添加检查或为 fifo
对象的断开连接添加事件处理程序。
似乎存在数据消失间隙的原因是因为循环继续迭代 i
并生成无法发送的字符串。
【讨论】:
以上是关于当阅读器断开连接时,命名管道 (FIFO) 数据会去哪里?的主要内容,如果未能解决你的问题,请参考以下文章