zoukankan      html  css  js  c++  java
  • Golang--Directional Channel(定向通道)

    Directional Channel

    通道可以是定向的(directional)。在默认情况下,通道将以双向的(bidirectional)形式运作,用户既可以把值放人通道,也可以从通道取出值;但是,通道也可以被限制为只能执行发送操作(send-only)或者只能执行接收操作(receive-only)。

    通常可以叫定向通道,也有人叫单向通道,两者其实都是指向这篇短文要讨论的Directional Channel

    下面直接举例子说明:

    package onlyChannelTest
    
    import (
    	"fmt"
    	"math/rand"
    	"sync"
    	"testing"
    	"time"
    )
    
    func TestOnlyChannel(t *testing.T)  {
    	var wg sync.WaitGroup
    	wg.Add(2)
    
    	c:= make(chan int, 3)
    	var send chan<- int = c
    	var recv <-chan int = c
    
    	go func() {
    		defer wg.Done()
    		for i := 0; i < 6; i++ {   // 注意这里是 6
    			fmt.Print("receive
    ")
    			fmt.Println(<-recv)
    		}
    	}()
    
    	go func() {
    		defer wg.Done()
    		defer close(c)
    
    		rand.Seed(time.Now().UTC().UnixNano())
    		for i := 0; i < 3; i++ {   // 这里是 3
    			fmt.Print("send
    ")
    			send <- rand.Intn(100)
    		}
    	}()
    
    	wg.Wait()
    }
    
    

    这里可以先猜一下运行结果,我直接贴出:

    image-20210131113121061

    后面的引起了我的注意:

    receive
    0
    

    是最让我困惑的地方,因为在一般印象内channel都是会阻塞的存在,而从上面结果看,第一个recv也是阻塞了)。但是后面的的recv却没有起到阻塞的作用,还是把c中的默认值0输出了。

    通过debug,不难看出的是,两个单向通道的发送和接收都是从一个缓冲通道中进行操作的,两个单项通道同属于一个双向通道,只不过他们被分别限制了接收和发送功能。

    image-20210131115618137

    通过debug,再次发现,在recv读取完之后,通道内并没有被“清空”,而是保有默认值。

    image-20210131122218881

    难道,recv并没有被阻塞?

    验证方法如下:

    		// defer close(c)
    

    选择注释掉发送Goroutine中的关闭通道。

    image-20210131123122579

    结果很明显,造成死锁,证明两个单向通道之间是有通信的,有阻塞的

    最后通过源码,还是找到了答案:

    image-20210131123806000

    书籍《Go Web编程》中同样有介绍:

    image-20210131181505963

    由此,为避免接收到不需要的无效零值,应修改接收Goroutine--receive的写法:

    go func() {
    		defer wg.Done()
    		for i := 0; i < 6; i++ { // 注意这里是 6
    			x, ok := <-recv
    			if ok {
    				fmt.Print("receive
    ")
    				fmt.Println(x)
    			}else{
    				break
    			}
    		}
    	}()
    

    image-20210131124040698

  • 相关阅读:
    解决xcode5升级后,Undefined symbols for architecture arm64:问题
    第8章 Foundation Kit介绍
    app 之间发送文件 ios
    iphone怎么检测屏幕是否被点亮 (用UIApplication的Delegate)
    CRM下载对象一直处于Wait状态的原因
    错误消息Customer classification does not exist when downloading
    How to resolve error message Distribution channel is not allowed for sales
    ABAP CCDEF, CCIMP, CCMAC, CCAU, CMXXX这些东东是什么鬼
    有了Debug权限就能干坏事?小心了,你的一举一动尽在系统监控中
    SAP GUI和Windows注册表
  • 原文地址:https://www.cnblogs.com/l1ng14/p/14352162.html
Copyright © 2011-2022 走看看