【发布时间】:2021-11-08 16:06:04
【问题描述】:
我有一个 goroutine 经常被阻止读取标准输入,像这样:
func routine() {
for {
data := make([]byte, 8)
os.Stdin.Read(data);
otherChannel <-data
}
}
例程等待通过标准输入读取 8 个字节并提供另一个通道。
我想从主线程优雅地停止这个 goroutine。但是,由于 goroutine 几乎总是会被阻止从标准输入读取,我找不到一个好的解决方案来强制它停止。我想到了类似的东西:
func routine(stopChannel chan struct{}) {
for {
select {
case <-stopChannel:
return
default:
data := make([]byte, 8)
os.Stdin.Read(data);
otherChannel <-data
}
}
}
但是,问题是如果在stopChannel 关闭时,stdin 中没有更多输入,goroutine 将保持阻塞状态而不返回。
有没有什么好办法让它在主线程需要的时候立即返回?
谢谢。
【问题讨论】:
-
您不能取消从 Stdin 读取,只需让 goroutine 运行并确保它在稍后完成时不会影响程序
-
golang.org/pkg/os/#File.SetReadDeadline 这样你可能会中断你的阅读
-
@GregGiacovelli:这将在标准输入上返回
ErrNoDeadline -
应该可以在标准输入和消费者之间粘贴
io.Pipe,然后关闭管道的一侧——这应该让消费者收到io.EOF,生产者返回io.ErrClosedPipe(所以它也可能退出)。我没有测试过,但值得研究。 -
@kostix,生产者不会被打断,因为它也会在 Read 中被阻塞。你可以设置一个 POSIX “自我管道技巧”,然后轮询实际的 fd 并关闭一个
os.Pipe,但这几乎不值得。
标签: go