用go的goroutine和channel實現一個簡單的“生產、消費”(帶有超時控制)小例子
阿新 • • 發佈:2019-02-10
直接上程式碼
1、沒有超時的時候
package main
import (
"fmt"
"time"
)
func main() {
//存放生產的channel
jobChan := make(chan int, 100)
//通知是否完成所有任務
endChan := make(chan bool)
go production(jobChan)
go worker(jobChan, endChan)
select {
case <-endChan:
fmt.Println("消費完成……………………" )
return
case <-time.After(time.Second * 20):
fmt.Println("超時………………………")
return
}
}
//消費
func worker(jobChan <-chan int, endChan chan bool) {
for job := range jobChan {
fmt.Println("消費:", job)
}
//消費結束,通知endChan
endChan <- true
}
//生產
func production(jobChan chan <- int) {
for i := 1; i <= 10; i++ {
fmt.Println("生產:", i)
jobChan <- i
}
//關閉channel防止消費阻塞
close(jobChan)
}
執行結果 :
可見生產和消費非同步併發執行。
2、當超時時 (timeout設定小點,並增加消費處理時間)
package main
import (
"fmt"
"time"
)
func main() {
//存放生產的channel
jobChan := make (chan int, 100)
//通知是否完成所有任務
endChan := make(chan bool)
go production(jobChan)
go worker(jobChan, endChan)
select {
case <-endChan:
fmt.Println("消費完成……………………")
return
case <-time.After(time.Second * 5):
fmt.Println("超時………………………")
return
}
}
//消費
func worker(jobChan <-chan int, endChan chan bool) {
for job := range jobChan {
fmt.Println("消費:", job)
//增加消費處理時間
time.Sleep(1 * time.Second)
}
//消費結束,通知endChan
endChan <- true
}
//生產
func production(jobChan chan<- int) {
for i := 1; i <= 10; i++ {
fmt.Println("生產:", i)
jobChan <- i
}
//關閉channel防止消費阻塞
close(jobChan)
}
執行結果
5秒之後超時(此時佇列裡尚有未處理完的資料)。