zoukankan      html  css  js  c++  java
  • [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
    
  • 相关阅读:
    RK3288 Android5.1系统编译
    RK3288 模块单独编译
    ubuntu 设置固定DNS
    PHP取整函数之ceil,floor,round,intval的区别
    PHP实现 APP端微信支付功能
    Laravel中服务提供者和门面模式
    laravel项目利用twemproxy部署redis集群的完整步骤
    PHP转盘抽奖算法
    laravel中短信发送验证码的实现方法
    PHP操作Redis常用
  • 原文地址:https://www.cnblogs.com/faithfu/p/12068414.html
Copyright © 2011-2022 走看看