與去打打左右,我扔在一起,這樣的代碼:寫這段代碼的更好的習慣用法?
package main
import "fmt"
const N = 10
func main() {
ch := make(chan int, N)
done := make(chan bool)
for i := 0; i < N; i++ {
go (func(n int, ch chan int, done chan bool) {
for i := 0; i < N; i++ {
ch <- n*N + i
}
done <- true
})(i, ch, done)
}
numDone := 0
for numDone < N {
select {
case i := <-ch:
fmt.Println(i)
case <-done:
numDone++
}
}
for {
select {
case i := <-ch:
fmt.Println(i)
default:
return
}
}
}
基本上我有N個頻道做了一些工作,並彙報其在同一通道 - 我想知道當所有的通道完成。所以我有這個其他的done
頻道,每個工作者的goroutine發送消息(消息無關緊要),並且這導致main將該線程計數爲完成。當計數到達N時,我們實際上完成了。
這是「好」嗎?有沒有更習慣性的做法呢?
編輯:爲了澄清一點,我很懷疑,因爲done
頻道似乎在做一個頻道關閉的工作,但我當然不能在任何goroutine中關閉頻道,因爲所有例程共享相同的頻道。所以我使用done
來模擬某種「緩衝關閉」的頻道。
edit2:原來的代碼並沒有真正的工作,因爲有時來自例程的done
信號在它剛剛放在ch
之前的int被讀取。需要一個「清理」循環。
哇!這是一些漂亮的代碼。 –