今天進行一個協程操作demo時總是報錯
//workerpool.go
package main
import (
"fmt"
"time"
)
//工作線程
func workerPool(jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Println("start job", j)
time.Sleep(time.Second) //模擬耗時工作
fmt.Println("finish job", j)
results <- j
}
}
func main() {
const numJobs = 5
jobs := make(chan int, numJobs) //
results := make(chan int, numJobs) //
go workerPool(jobs, results)
for i := 1; i <= numJobs; i++ {
jobs <- i
}
close(jobs)
for r := range results {
fmt.Println("results :", r)
}
}
go run workerpool.go 報錯
start job 1
finish job 1
start job 2
results : 1
finish job 2
start job 3
results : 2
finish job 3
start job 4
results : 3
finish job 4
start job 5
results : 4
finish job 5
fatal error: all goroutines are asleep - deadlock!
results : 5
goroutine 1 [chan receive]:
main.main()
workerpool.go:30 +0x19d
asleep就是說協程都在睡覺沒做事
問題應該出在遍歷jobs上, jobs遍歷完沒數據可操作了,引發 asleep - deadlock 報錯
改進方法:
1、是無限循環輸入數據到jobs
2、用waitGroup
方法1的無限循環輸入數據就不做介紹了,比較簡單
下面展示一下方法2使用waitGroup的方式
package main
import (
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
//工作線程
func workerPool(jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Println("start job", j)
time.Sleep(time.Second)
fmt.Println("finish job", j)
results <- j
}
}
func init() {
wg = sync.WaitGroup{}
}
func main() {
const numJobs = 5
jobs := make(chan int) //
results := make(chan int) //
go workerPool(jobs, results)
go func() {
for r := range results {
fmt.Println("results :", r)
wg.Done()//接收到數據,表示完成了一份工作
}
}()
for i := 1; i <= numJobs; i++ {
wg.Add(1)//標記開始一份工作
jobs <- i
}
wg.Wait()
}
正常運行結果如下:
start job 1
finish job 1
start job 2
results : 1
finish job 2
start job 3
results : 2
finish job 3
start job 4
results : 3
finish job 4
start job 5
results : 4
finish job 5
results : 5
Process finished with exit code 0
