gpt4 book ai didi

go - 优雅地停止被阻塞的 goroutine

转载 作者:行者123 更新时间:2023-12-04 13:44:47 25 4
gpt4 key购买 nike

我有一个经常被阻止读取标准输入的 goroutine,如下所示:

func routine() {
for {
data := make([]byte, 8)
os.Stdin.Read(data);
otherChannel <-data
}
}

该例程等待通过 stdin 读取 8 个字节并馈送另一个 channel 。

我想从主线程优雅地停止这个 goroutine。然而,由于 goroutine 几乎总是会被阻止从 stdin 读取,我找不到一个好的解决方案来强制它停止。我想过这样的事情:
func routine(stopChannel chan struct{}) {
for {
select {
case <-stopChannel:
return
default:
data := make([]byte, 8)
os.Stdin.Read(data);
otherChannel <-data
}
}
}

但是,问题是如果 stopChannel时stdin中没有更多的输入关闭,goroutine 将保持阻塞状态并且不会返回。

有什么好的方法可以让它在主线程需要时立即返回吗?

谢谢。

最佳答案

检测 os.Stdin已关闭:检查 os.Stdin.Read() 返回的错误值.
额外的一点:尽管您声明在您的情况下您将始终收到 8 个字节的块,但您仍应检查您是否确实收到了 8 个字节的数据。

func routine() {
for {
data := make([]byte, 8)
n, err := os.Stdin.Read(data)

// error handling : the basic thing to do is "on error, return"
if err != nil {
// if os.Stdin got closed, .Read() will return 'io.EOF'
if err == io.EOF {
log.Printf("stdin closed, exiting")
} else {
log.Printf("stdin: %s", err)
}
return
}

// check that 'n' is big enough :
if n != 8 {
log.Printf("short read: only %d byte. exiting", n)
return // instead of returning, you may want to keep '.Read()'ing
// or you may use 'io.ReadFull(os.Stdin, data)' instead of '.Read()'
}

// a habit to have : truncate your read buffers to 'n' after a .Read()
otherChannel <-data[:n]
}
}

关于go - 优雅地停止被阻塞的 goroutine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50776156/

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