zoukankan      html  css  js  c++  java
  • Nil Channels Always Block(Go语言中空管道总是阻塞)

    译自:https://www.godesignpatterns.com/2014/05/nil-channels-always-block.html 

    原作者:Alex Lockwood

      在本篇文章中,我们将讨论 nil channel 在 Go 中的使用。nil channel 无论是接收还是发送都会永久阻塞:

    // Create an uninitialized (nil) channel.
    var ch chan struct{}
    
    // Receiving on a nil channel blocks forever.
    <-ch
    
    // Sending on a nil channel will also block forever.
    ch <- struct{}{}

      nil channel 看上去似乎没有什么用,甚至曾经在你的项目中引起 bug(例如忘记在使用 channels 前,用 make 初始化)。但是,可以通过几种巧妙的方式利用此属性,特别是当你需要在 select 语句中动态禁用一个 case:

    if disableSelectCase {
    	ch1 = nil
    } else {
    	ch1 = nonNilChan
    }
    
    select {
    case <-ch1:
    	// This case will only be considered if ch1 is not nil.
    // 这个 case 直到 ch1 不是 nil 时才会被考虑 case <-ch2: // This case will always be considered (assuming ch2 is non-nil). }

      上面的 code 阐明了这样一个特征,当 select 语句中的一个case 是 nil channel 时,它将会选择性忽略。如果 boolean 类型的 disableSelectCase 为 true ,此时会将 nil 赋值给 ch1,从而阻止 ch1 channel 被 select 语句考虑。

      这种特性也被用来防止空循环,比如当你需要等待多个 channels 关闭时:

    // WARNING! Spin loop might occur!
    var isClosed1, isClosed2 bool
    for !isClosed1 || !isClosed2 {
    	select {
    	case _, ok := <-ch1:
    		if !ok {
    			isClosed1 = true
    		}
    	case _, ok := <-ch2:
    		if !ok {
    			isClosed2 = true
    		}
    	}
    }
    

      如果上面的代码中两个 channel 有一个被关闭,将会在你的项目中引起一个小 bug。因为被关闭的 channel 永远不会阻塞,如果 ch1 被关闭,ch1 在随后的循环迭代中将总是准备被接收。作为结果,程序将陷入死循环,还有就是 case <- ch2 也许再也没有机会被执行。

      为了解决这个问题,我们可以利用 nil channel 总是阻塞的特性:

    // Safely disable channels after they are closed.
    for ch1 != nil || ch2 != nil {
    	select {
    	case _, ok := <-ch1:
    		if !ok {
    			ch1 = nil
    		}
    	case _, ok := <-ch2:
    		if !ok {
    			ch2 = nil
    		}
    	}
    }
    

      

  • 相关阅读:
    CentOS 7.X 关闭SELinux
    删除或重命名文件夹和文件的方法
    centos7-每天定时备份 mysql数据库
    centos7 tar.gz zip 解压命令
    MySQL5.6/5.7/8.0版本授权用户远程连接
    下载CentOS7系统
    使用js实现tab页签切换效果
    sql优化常用的几种方法
    mysql 多表联查的快速查询(索引)
    【图论】强连通分量+tarjan算法
  • 原文地址:https://www.cnblogs.com/DillGao/p/9342883.html
Copyright © 2011-2022 走看看