1 回答

TA貢獻1858條經驗 獲得超8個贊
好的,我們開始吧。首先,請注意您的代碼中存在一些問題。然后修復它們。
正如Adrian所說,從已經關閉或沒有元素的通道中讀取。在您的工作人員功能中,您正在這樣做。當您在另一個工作人員關閉輸入通道后從輸入通道讀取元素時,就會發生這種情況。
func worker(input chan int, output chan<- int) {
defer close(input)
...
for {
element, more := <-input
...
}
}
那么,為什么在所有工作人員完成后不關閉輸入通道?
在解決了輸入通道的問題后,當您嘗試從輸出通道讀取時,會出現另一個問題。此外,您不會在輸出通道上發送任何內容。如果您不需要該頻道,那么為什么要使用該頻道。而且這個輸出通道是無緩沖的(大小為0的通道和發送接收應該同時,否則會出現死鎖情況)??矗瑥倪@里和這里緩沖與無緩沖。也許網絡上有更多有用的文檔。感謝我的朋友Nightfury1204從他的這篇文章中獲得了關于緩沖與非緩沖頻道的第一個鏈接。
outputChannel := make(chan int) // unbuffered, no size is defined
...
for elem := range outputChannel {
fmt.Println("Output: ", elem)
}
所以,如果你想向輸出通道發送一些東西,那么邏輯是你自己的。例如,您可以在工作人員中完成輸入通道處理后發送一些內容。在這種情況下,將您的輸出通道聲明為長度為 4 的緩沖通道(因為您正在運行 4 個工作人員)。完成所有工作人員后,關閉您的輸出通道,然后閱讀。
outputChannel := make(chan int, 4) // buffered
...
// after finishing all your workers
close(outputChannel)
for elem := range outputChannel {
fmt.Println("Output: ", elem)
}
需要注意的是,使用sync.WaitGroupfrom "sync"package 來等待一組 goroutine 完成。
請參見下面的示例:https: //play.golang.org/p/WAqwyR0ggNN
import "fmt"
import "sync"
func main() {
inputChannel := make(chan int, 1)
outputChannel := make(chan int, 4)
var wg sync.WaitGroup
wg.Add(4)
inputChannel <- 100
numWorkers := 4
for i := 0; i < numWorkers; i++ {
go func() {
defer wg.Done()
for {
select {
case element := <-inputChannel:
fmt.Println("Input: ", element)
element--
if element != 0 {
inputChannel <- element
}
default:
outputChannel<-0
fmt.Println("All Jobs Processed", len(outputChannel))
return
}
}
}()
}
wg.Wait()
close(inputChannel)
close(outputChannel)
for elem := range outputChannel {
fmt.Println("Output: ", elem)
}
}
- 1 回答
- 0 關注
- 122 瀏覽
添加回答
舉報