/ / Schreiben Sie mehr als 4 KByte in exec.Cmd.StdinPipe () - go, process, pipe, ipc

Schreibe mehr als 4K Bytes nach exec.Cmd.StdinPipe () - go, process, pipe, ipc

Problem

Beim Schreiben von Daten mit mehr als 4096 Byte in Cmd.StdinPipe In Go wird die Programmverarbeitung unter Windows gestoppt. Dieses Phänomen tritt nicht auf, wenn derselbe Code unter Linux ausgeführt wird oder wenn ein Prozess mit Goroutine geschrieben wird.

Frage

Die Verarbeitung wird nicht fortgesetzt _, err = in.Write ([] byte {"0"}) (4097 Bytes) in dem unten gezeigten Code. Warum ist das?

Warum kommt es bei Goroutine oder unter Linux nicht vor?

*** Golang-Referenz beschreibt Cmd.StdinPipe unter Verwendung von Goroutine als ein Beispiel, und mein problem wurde auch gelöst. Diese Frage ergibt sich aus der Neugier auf Go.

package main

import (
"bytes"
"fmt"
"io"
"log"
"os/exec"
)

func main() {
cmd := exec.Command("more")

pype, err := cmd.StdinPipe()
if err != nil {
log.Fatal(err)
}

bytes4k := generateBytes(1024 * 4) // Works on Linux, but not Windows.
// bytes4k := generateBytes(1024 * 64) // Don"t works on Linux and Windows.
fmt.Println("bytes generated.")

// go writeBytes(pype, bytes4k) // Works fine!
writeBytes(pype, bytes4k) // Can"t write. Write is locked.

err = cmd.Run()
if err != nil {
log.Fatal(err)
}

fmt.Println("finished.")
}

func generateBytes(num int) []byte {
byte := bytes.NewBuffer(make([]byte, 0, num))
for i := 0; i < num; i++ {
byte.WriteByte("0")
}
return byte.Bytes()
}

func writeBytes(in io.WriteCloser, bytes []byte) {
defer in.Close()

_, err := in.Write(bytes)
if err != nil {
log.Fatal(err)
}
fmt.Println("written bytes to pipe.")

_, err = in.Write([]byte{"0"}) // Why this code stops at 4097 bytes?
if err != nil {
log.Fatal(err)
}
fmt.Println("written 1 byte to pipe.")
}

Verifizierte Versionen

  • go version go1.10.1 windows / amd64
  • go version go1.10.1 linux / amd64

Antworten:

7 für die Antwort № 1

Schreibe nur Blöcke, wenn kein Platz mehr in der Pipe ist. Während die Pipe in Windows 4 KB groß sein kann, ist sie in Linux viel größer. Von Rohr (7):

... seit Linux 2.6.11 beträgt die Pipe-Kapazität 16 Seiten (d.h. 65.536 Bytes in einem System mit einer Seitengröße von 4096 Bytes) ...

Auf diese Weise erhalten Sie unter Linux wahrscheinlich das gleiche Ergebnis wie unter Windows, wenn Sie in eine Pipe schreiben, in der niemand liest, aber Sie müssen weitaus mehr Daten in die Pipe schreiben, bis Sie diese Situation erreichen.


0 für die Antwort № 2

Dies wurde bereits beantwortet. Hier ist die Problemumgehung, die Sie wahrscheinlich verwenden möchten, wenn Sie auf dieses Problem stoßen. Verwenden Sie stattdessen den gepufferten Writer, der in der Bufio Paket. Auf diese Weise können Sie einen Writer mit einem größeren Puffer umschließen, über den Sie die vollständige Kontrolle haben.