проблем
Когато пишете данни над 4096 байта до Cmd.StdinPipe
в Go, обработката на програмата спира на Windows. Това явление не се появява, когато един и същ код работи на Linux или когато пишете процес, използвайки goroutine.
въпрос
Обработката няма да продължи _, err = in.Write ([] byte {"0"})
(4097 байта) в кода, показан по-долу. Защо е това?
Защо не се случва с goroutine или в Linux?
*** Препратката към Golang описва Cmd.StdinPipe, използвайки goroutine като пример, и проблемът ми също е решен. Този въпрос възниква от любопитството към 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.")
}
Проверени версии
- go версия go1.10.1 windows / amd64
- go версия go1.10.1 linux / amd64
Отговори:
7 за отговор № 1Писане само на блокове, ако в тръбата няма повече място. Въпреки че размерът на тръбата в Windows може да бъде 4k, той е много по-голям в Linux. от тръба (7):
... От Linux 2.6.11, капацитетът на тръбата е 16 страници (т.е. 65,536 байта в система с размер на страницата 4096 байта) ...
По този начин вероятно ще получите същия резултат в Linux, както и в Windows, когато пишете в тръба, където никой не чете, но трябва да запишете много повече данни в тръбата, докато стигнете до тази ситуация.
0 за отговор № 2
На това вече е отговорено, ето това вероятно ще искате да използвате, ако се сблъскате с този проблем - използвайте вместо това буферирания писател, наличен в bufio пакет. Това ви позволява да обгърнете писател с по-голям буфер, над който имате пълен контрол.