gpt4 book ai didi

go - golang : `os.Stdin.Read` doesn't handle input consisting of a sole EOF?

转载 作者:行者123 更新时间:2023-12-01 21:17:21 25 4
gpt4 key购买 nike

我是writing猫,在接收第一个字节时超时。我有它工作,除了它不能处理echo -n:

❯ echo -n | time possiblycat 1000  # 1000 is the timeout in milliseconds                                                                                        
possiblycat 1000 0.00s user 0.00s system 0% cpu 1.008 total; max RSS 1864
cat本身与此无关。它会注意到EOF并立即退出:
❯ echo -n | time cat                                                                                                      
cat 0.00s user 0.00s system 71% cpu 0.003 total; max RSS 664
这是 possiblycat的全部来源:
package main

import (
"io"
"io/ioutil"
"os"
"strconv"
"time"
)

func main() {
wait := 10
if len(os.Args) >= 2 {
waitDummy, err := strconv.Atoi(os.Args[1])
if err != nil {
panic(err)
}
wait = waitDummy
}

b := make(chan byte, 1)
go scan(b)

select {
case res := <-b:
inBytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {
panic(err)
}
stdin := append([]byte{res}, inBytes...)
_, err2 := os.Stdout.Write(stdin)
if err2 != nil {
panic(err2)
}
case <-time.After(time.Duration(wait) * time.Millisecond):
os.Exit(1)
}
}

func scan(out chan byte) {
var b []byte = make([]byte, 1)
_, err := os.Stdin.Read(b)
if err == io.EOF {
return
} else if err != nil {
panic(err)
}
out <- b[0]
}

有关的:
  • Does echo -n | … send an EOF to the pipe?
  • 最佳答案

    os.Stdin.Read返回EOF时,您退出在其自己的goroutine中运行的scan函数。
    但是,并没有采取任何措施告诉主goroutine所有输入均已处理。它正在等待b channel 上的数据或超时。由于b上没有数据,因此达到了超时。
    为了正确处理此问题,err == io.EOF情况应向主goroutine发出信号,表明没有其他工作要做。一种常见的模式(但肯定不是唯一的一种)是具有一个done channel ,该 channel 指示所有工作已完成。

      done := make(chan bool, 1)
    go scan(b, done)

    select {
    case res := <-b:
    ...
    case <-done:
    os.Exit(1)
    case <-time.After(time.Duration(wait) * time.Millisecond):
    os.Exit(1)
    }
    }

    func scan(out chan byte, done chan bool) {
    var b []byte = make([]byte, 1)
    _, err := os.Stdin.Read(b)
    if err == io.EOF {
    fmt.Println("got EOF, exiting")
    done <- true
    return
    } else if err != nil {
    ...
    }
    另一种(甚至更简单的)替代方法是在完成后简单地关闭数据 channel :
    func scan(out chan byte) {
    var b []byte = make([]byte, 1)
    _, err := os.Stdin.Read(b)
    if err == io.EOF {
    fmt.Println("got EOF, exiting")
    close(out)
    return
    } else if err != nil {
    panic(err)
    }
    out <- b[0]
    }

    关于go - golang : `os.Stdin.Read` doesn't handle input consisting of a sole EOF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63981760/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com