昨天探討了dead lock,引進了buffer.
在昨天的程式中,main()必須使用time.Sleep來延遲,
以等待goroutine完成.這樣的方式並不理想.
我們來思考一下,現在channel已經有buufer,可以不被block住.
那channel除了傳遞要處理的資料以外,是否還能使用第二個channel
來傳遞工作已經完成了呢?
來看看以下的程式:
// hello70
// producer_consumer
package main
import (
"fmt"
"time"
)
// integer producer
func numGen(start, count int, out chan<- int) {
for i := 0; i < count; i++ {
out <- start
start += count
}
close(out)
fmt.Printf("Producer: 送完 -%v\n", time.Now())
}
// integer consumer
func numEchoRange(in <-chan int, done chan<- bool) {
for num := range in {
time.Sleep(time.Second)
fmt.Printf("consumer: 收到%2d-%v\n", num, time.Now())
}
done <- true
}
func main() {
numChan := make(chan int, 100)
done := make(chan bool)
go numGen(0, 10, numChan)
go numEchoRange(numChan, done)
<-done
fmt.Println("Main():所有的工作都已完成!")
}
執行結果:
./hello70
Producer: 送完 -2014-10-17 17:13:57.634881246 +0800 CST
consumer: 收到 0-2014-10-17 17:13:58.635071652 +0800 CST
consumer: 收到10-2014-10-17 17:13:59.635202264 +0800 CST
consumer: 收到20-2014-10-17 17:14:00.635333501 +0800 CST
consumer: 收到30-2014-10-17 17:14:01.635465749 +0800 CST
consumer: 收到40-2014-10-17 17:14:02.635604602 +0800 CST
consumer: 收到50-2014-10-17 17:14:03.635718973 +0800 CST
consumer: 收到60-2014-10-17 17:14:04.635823232 +0800 CST
consumer: 收到70-2014-10-17 17:14:05.635948649 +0800 CST
consumer: 收到80-2014-10-17 17:14:06.636082095 +0800 CST
consumer: 收到90-2014-10-17 17:14:07.636214144 +0800 CST
Main():所有的工作都已完成!
Producer一口氣把資料都傳進資料channel,然後關閉.
consumer使用 range在 chaneel,
好整以暇的慢慢列印,最後把信號傳遞給Main().
可以看到實際上信號的內容,根本不在乎,就是一個信號.
最終由Main()印出訊息,並做整個離開的清理工作,程式執行完成.