Heim >Backend-Entwicklung >Golang >io.Pipe und Deadlock beim Versuch zu schreiben/lesen
Ich habe stundenlang versucht, die zugrunde liegende Logik zu verstehen, kam aber nicht voran. Der folgende Code gibt nach der ersten Iteration einen Deadlock zurück. Wenn ich den Schreiber vorher schließe io.copy
, verschwindet der Deadlock, aber es wird nichts gedruckt (da das schreibende Ende der Pipe vor dem Lesen geschlossen wird)
func main() { reader, writer := io.pipe() c := make(chan string) go func() { for i := 0; i < 5; i++ { text := fmt.sprintf("hello %vth time", i+1) c <- text } close(c) }() for msg := range c { msg = fmt.sprintf("\nreceived from channel -> %v\n", msg) go fmt.fprint(writer, msg) io.copy(os.stdout, reader) writer.close() } }
Dies ist der Fehler nach dem Ausführen des Codes
received from channel -> hello 1th time fatal error: all goroutines are asleep - deadlock! goroutine 1 [select]: io.(*pipe).read(0xc000130120, {0xc00013e000, 0x8000, 0xc00011e001?}) /usr/lib/go/src/io/pipe.go:57 +0xb1 io.(*PipeReader).Read(0x0?, {0xc00013e000?, 0xc00011e050?, 0x10?}) /usr/lib/go/src/io/pipe.go:136 +0x25 io.copyBuffer({0x4bde98, 0xc00011e050}, {0x4bddb8, 0xc00012e018}, {0x0, 0x0, 0x0}) /usr/lib/go/src/io/io.go:427 +0x1b2 io.Copy(...) /usr/lib/go/src/io/io.go:386 os.genericReadFrom(0x101c00002c500?, {0x4bddb8, 0xc00012e018}) /usr/lib/go/src/os/file.go:161 +0x67 os.(*File).ReadFrom(0xc00012e008, {0x4bddb8, 0xc00012e018}) /usr/lib/go/src/os/file.go:155 +0x1b0 io.copyBuffer({0x4bde38, 0xc00012e008}, {0x4bddb8, 0xc00012e018}, {0x0, 0x0, 0x0}) /usr/lib/go/src/io/io.go:413 +0x14b io.Copy(...) /usr/lib/go/src/io/io.go:386 main.pipetest() /home/stranger/source-code/golang/ipctest/pipes/main.go:39 +0x1ae main.main() /home/stranger/source-code/golang/ipctest/pipes/main.go:10 +0x17 goroutine 18 [chan send]: main.pipetest.func1() /home/stranger/source-code/golang/ipctest/pipes/main.go:29 +0x85 created by main.pipetest /home/stranger/source-code/golang/ipctest/pipes/main.go:26 +0x17a exit status 2
io.copy
不断尝试复制,直到读取器到达 eof(在本例中,当管道关闭时)。由于您在 io.copy
结束后调用 writer.close()
after ,因此 io.copy
Versuchen Sie weiter zu kopieren, bis der Leser eof erreicht (in diesem Fall, wenn die Pipe geschlossen ist). Da Sie writer.close()
after aufrufen, nachdem
nie eof sehen und für immer hängen bleiben. close
able 对象只应关闭一次,并且在 close
d ausgegangen. Wenn Sie sie wiederverwenden müssen, sollten Sie eine neue Instanz erstellen.
🎜Dies ist eine funktionierende Überarbeitung des Codes: 🎜func main() { c := make(chan string) go func() { for i := 0; i < 5; i++ { text := fmt.Sprintf("hello %vth time", i+1) c <- text } close(c) }() for msg := range c { msg = fmt.Sprintf("\nreceived from channel -> %v\n", msg) // Create a new pipe for this message. reader, writer := io.Pipe() go func() { fmt.Fprint(writer, msg) // Close the pipe after writing the message. writer.Close() }() io.Copy(os.Stdout, reader) } }
Das obige ist der detaillierte Inhalt vonio.Pipe und Deadlock beim Versuch zu schreiben/lesen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!