![](/img/trans.png)
[英]How to stop goroutine blocked by external I/O started for process?
[英]Stop goroutine that is blocked gracefully
我有一個經常被阻止讀取標准輸入的 goroutine,如下所示:
func routine() {
for {
data := make([]byte, 8)
os.Stdin.Read(data);
otherChannel <-data
}
}
該例程等待通過 stdin 讀取 8 個字節並饋送另一個通道。
我想從主線程優雅地停止這個 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]
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.