1 回答

TA貢獻2011條經(jīng)驗 獲得超2個贊
你有一個死鎖,因為你的偶數(shù)和奇數(shù) goroutines 在發(fā)送到時被阻止,out
因為沒有從中讀取任何內(nèi)容。為什么什么都不讀out
?因為main
goroutine 在發(fā)送到時被阻止,input
因為沒有從中讀取任何內(nèi)容。為什么沒有讀取input
?因為從中讀取的兩個 goroutine 被阻塞了。
此外,除非您將它們的內(nèi)容包裝在其中,否則它們filterEven
和filterOdd
都只會運行一次for { }
(但是在您之前它們永遠不會停止break
)。另一方面,當沒有任何東西可以寫入時,range even
將阻塞(并且range odd
永遠不會發(fā)生)even
,因為range
只有當通道關(guān)閉或被break
調(diào)用時,通道才會停止。
一般來說,只要您知道何時可以關(guān)閉通道,這些都不是很難解決的問題。根據(jù)您的描述,這變得更加困難。沒有一個 goroutine 知道什么時候可以關(guān)閉input
,因為所有三個都向它寫入,兩個也從它讀取。您可以使用 async.WaitGroup
來確保input
在關(guān)閉之前已處理您放入通道的所有內(nèi)容。一旦它關(guān)閉,另外兩個 goroutine 就可以使用它作為關(guān)閉它們自己的通道break
或return
完成運行的信號。
但是,對in
和out
通道的寫入仍然會阻塞,直到有相應(yīng)的讀取,因為它們是無緩沖的。但是,如果您通過將大小指定為 的第二個參數(shù)來緩沖它們,則make
在通道已滿之前不會阻止寫入。既然你既不知道even
或odd
將有更多的寫入他們比什么main
送input
,你可以使用它作為安全緩沖能力。
這是WaitGroup
為您的代碼使用帶緩沖通道的示例:https : //play.golang.org/p/VXqfwUwRcx
如果您不想要緩沖通道,您還可以使用另一對 goroutines 來捕獲值并main
在完成后將它們作為切片發(fā)送回。這種方式寫在even
和odd
渠道不會阻塞:https://play.golang.org/p/i5vLDcsK1v
否則,如果不需要一次打印每個頻道的內(nèi)容,您可以使用這兩個額外的 goroutine 從頻道中讀取并立即打印:https : //play.golang.org/p/OCaUTcJkKB
- 1 回答
- 0 關(guān)注
- 154 瀏覽
添加回答
舉報