利用channe關閉任務
package ch21
import (
"fmt"
"testing"
"time"
)
//判斷是否有取消任務信號
func isCancelled(cancelChan chan bool) bool {
select {
case <-cancelChan:
return true
default:
return false
}
}
//只要1個協程能關閉
func cancel_1(cancelChan chan bool) {
cancelChan <- true
}
//所有協程都能關閉
func cancel_2(cancelChan chan bool) {
close(cancelChan)
}
func TestCancelChannel(t *testing.T) {
var wg sync.WaitGroup
cancelChan := make(chan bool, 1)
for i := 0; i < 5; i++ {
wg.Add(1)
go func(i int, ch chan bool) {
for {
if isCancelled(cancelChan) {
fmt.Println(i, "cancelled")
} else {
fmt.Println(i, "done")
}
wg.Done()
break
}
}(i, cancelChan)
}
cancel_2(cancelChan)
wg.Wait()
}
一般實現方法,通過channel傳遞關閉信號
缺點:發送信號的個數和需要關閉的協程數量必須一致,耦合性強
cancel_1()
執行結果
=== RUN TestCancelChannel
4 cancelled
0 done
1 done
2 done
3 done
--- PASS: TestCancelChannel (0.00s)
利用channel的廣播機制
channel特性,被close之后,channel仍然可讀,不但可以讀取出已發送的數據,還可以不斷的讀取零值,
但是如果通過range讀取,channel關閉后for循環會跳出:
通過i, ok := <-c
可以查看Channel的狀態,判斷值是零值還是正常讀取的值。
使用channel close特性,可以實現廣播功能
cancel_2()
執行結果
=== RUN TestCancelChannel
4 cancelled
1 cancelled
0 cancelled
2 cancelled
3 cancelled