• [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
    
  • 相关阅读:
    JavaIO流(四) File文件对象
    Java IO流(三) 字符流Reader和Writer
    Java IO流(二) 字节流InputStream和OutputStream
    Java IO流(一)入门
    Decorator(装饰者)模式
    Listener(监听器)
    Filter(过滤器)
    Java开发入门
    啊哈哈,写博客的第一天
    MySQL变量
  • 原文地址:https://www.cnblogs.com/faithfu/p/12068414.html
Copyright © 2020-2023  润新知