2 回答

TA貢獻1851條經驗 獲得超3個贊
您可以創建一個生產者/消費者系統:https : //play.golang.org/p/rks0gB3aDb
func main() {
ch := make(chan int)
clients := 4
// make it buffered, so all clients can fail without hanging
notifyCh := make(chan struct{}, clients)
go produce(100, ch, notifyCh)
var wg sync.WaitGroup
wg.Add(clients)
for i := 0; i < clients; i++ {
go func() {
consumer(ch, notifyCh)
wg.Done()
}()
}
wg.Wait()
}
func consumer(in chan int, notifyCh chan struct{}) {
fmt.Printf("Start consumer\n")
for i := range in {
<-time.After(100 * time.Millisecond)
if i == 42 {
fmt.Printf("%d fails\n", i)
notifyCh <- struct{}{}
return
} else {
fmt.Printf("%d\n", i)
}
}
fmt.Printf("Consumer stopped working\n")
}
func produce(N int, out chan int, notifyCh chan struct{}) {
for i := 0; i < N; i++ {
select {
case out <- i:
case <-notifyCh:
close(out)
return
}
}
close(out)
}
生產者將數字從 0 到 99 推送到通道,消費者一直消費直到通道關閉。在 main 中,我們創建了 4 個客戶端并將它們添加到一個等待組中,以可靠地檢查每個 goroutine 是否返回。每個消費者都可以在 notifyCh 上發信號,生產者停止工作并且不再產生更多的數字,因此所有消費者都在他們當前的數字之后返回。
還有一個選項可以創建4個go例程,等待它們全部返回,開始接下來的4個go例程。但這會增加等待的開銷。
既然你提到了素數,這里有一個非??岬乃財担篽ttps ://golang.org/doc/play/sieve.go

TA貢獻1936條經驗 獲得超7個贊
您是要為每個例程創建一個公共頻道還是一個頻道,取決于您想要什么。
如果你只想在里面放一些數字(或更一般的 - 請求)并且你不關心哪個 goroutine 提供服務,那么當然最好共享一個頻道。例如,如果您希望 goroutine1 為前 250 個請求提供服務,那么您當然不能共享頻道。
對于通道是一個很好的做法,將其用作輸入或輸出。發送者如何發送最簡單的事情,他完成了關閉通道。關于這一點的好文章是https://blog.golang.org/pipelines
問題中沒有提到的是 - 您是否還需要另一個通道(或多個通道)或任何其他通信原語來獲得結果。這是比喂食更有趣的渠道。
應該發送什么信息 - 應該發送它,在每次 doTest 之后發送一個 bool,或者只知道什么時候完成了所有事情(在這種情況下,bool 都不需要只關閉一個通道)?
如果你喜歡程序一開始就失敗。比我更喜歡使用緩沖共享通道來提供數字。不要忘記關閉它,當所有數字都將被饋送時。
另一個無緩沖的 chan 讓主線程知道,測試已經完成。它可以是通道,在那里你只輸入數字,測試失敗的地方,或者如果你還想要一個肯定的結果 - 包含數字和結果的結構通道,或從 doTest 返回的任何其他信息。
關于頻道的非常好的文章也是http://dave.cheney.net/2014/03/19/channel-axioms
您的四個 goroutine 中的每一個都可以報告失?。ㄍㄟ^發送錯誤和關閉通道)。但是當所有數字都通過并且饋送通道關閉時,goroutines 應該做的是gotcha。關于那也是不錯的文章http://nathanleclaire.com/blog/2014/02/15/how-to-wait-for-all-goroutines-to-finish-executing-before-continuing/
- 2 回答
- 0 關注
- 210 瀏覽
添加回答
舉報