gonamed-pipes

Read continuously from a named pipe


I would like to know what other options I have in order to read continuously from a named pipe using golang. My current code relies on a infinite for loop running inside a gorutine; but that keeps one CPU at 100% usage.

func main() {
....

var wg sync.WaitGroup
fpipe, _ := os.OpenFile(namedPipe, os.O_RDONLY, 0600)
defer fpipe.Close()
    
f, _ := os.Create("dump.txt")
defer f.Close()
var buff bytes.Buffer
    
wg.Add(1)
go func() {
        for {
          io.Copy(&buff, fpipe)
          if buff.Len() > 0 {
              buff.WriteTo(f)
           }
         }
    }()

    wg.Wait()
}

Solution

  • A named pipe reader will receive EOF when there are no writers left. The solution outside of this code is to make sure there is always one writer process holding the file descriptor, though it doesn't need to write anything.

    Within the Go program, if you want to wait for a new writer, you will have to poll the io.Reader in your for loop. Your current code does this with a busy loop, which will consume 100% of 1 cpu core. Adding a sleep and a way to return on other errors will work around the issue:

    for {
        err := io.Copy(&buff, fpipe)
        if buff.Len() > 0 {
            buff.WriteTo(f)
        }
    
        if err != nil {
            // something other than EOF happened
            return
        }
    
        time.Sleep(100 * time.Millisecond)
    }