[Go] 基础系列二:channel的关闭和广播

利用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
posted @ 2019-12-19 16:09  faithfu  阅读(1411)  评论(0编辑  收藏  举报