zoukankan      html  css  js  c++  java
  • golang go语言通道类型的通道示例 通道的通道

    几点注意:go的无缓存通道

    通道make 创建后,即使里面是空的,也可以取里面内容。但是程序会被阻塞。

    通道的规则是没人取,是不能往里面放的。放的线程会阻塞。

    最外层的requestChan相当于一个总线或媒介。

    生产者goroutineD直接从requestChan通道里面再取一个内部通道responseChan,这时不管responseChan创建没有,如果没有的话会阻塞,直到取到后,往responseChan通道里面扔内容。

    消费者goroutineC创建一个内部通道responseChan,然后就可以提取里面的内容。如果没有阻塞直到收到。

    收取开始后,requestChan中介通道里面就没有responseChan内部通道了?

    package main
    
    import "fmt"
    import "time"
    
    func main() {
    
        // make the request chan chan that both go-routines will be given
        requestChan := make(chan chan string)
    
        // start the goroutines
        go goroutineC(requestChan)
        go goroutineD(requestChan)
    
        // sleep for a second to let the goroutines complete
        time.Sleep(20 * time.Second)
    
    }
    
    func goroutineC(requestChan chan chan string) {
        time.Sleep(5 * time.Second)
    
        fmt.Println("goroutineC create response chan.")
        // make a new response chan
        responseChan := make(chan string)
    
        // send the responseChan to goRoutineD
        requestChan <- responseChan
    
        fmt.Println("goroutineC waiting to read.")
        // read the response
        response := <-responseChan
    
        fmt.Println("goroutineC get Response: ", response)
    
    }
    
    func goroutineD(requestChan chan chan string) {
    
        // read the responseChan from the requestChan
        fmt.Println("		goroutineD wait to get response chan.")
        responseChan := <-requestChan
        fmt.Println("		goroutineD has gotten response chan.")
        fmt.Println("		goroutineD sleep 5 minutes.")
        time.Sleep(5 * time.Second)
        // send a value down the responseChan
        fmt.Println("		goroutineD send wassup.")
        responseChan <- "wassup!"
    
    }

    改成如下代码执行,发现通道的内容生成好之后也无法放入通道,需要有人取内容时,才能放入。这是go的无缓存通道规则

    package main
    
    import "fmt"
    import "time"
    
    func main() {
    
        // make the request chan chan that both go-routines will be given
        requestChan := make(chan chan string)
    
        // start the goroutines
        go goroutineC(requestChan)
        go goroutineD(requestChan)
    
        // go goroutineC(requestChan)
        // go goroutineD(requestChan)
    
        // sleep for a second to let the goroutines complete
        time.Sleep(40 * time.Second)
    
    }
    
    func goroutineC(requestChan chan chan string) {
    
        fmt.Println("goroutineC create response chan.")
        // make a new response chan
    
        responseChan := make(chan string)
    
        // send the responseChan to goRoutineD
        requestChan <- responseChan
    
        fmt.Println("goroutineC waiting to read.")
        // read the response
        response := <-responseChan
    
        fmt.Println("goroutineC get Response: ", response)
    
        ////read again/////////
        // read the response
        response = <-responseChan
    
        fmt.Println("goroutineC get Response: ", response)
    
    }
    
    func goroutineD(requestChan chan chan string) {
        time.Sleep(5 * time.Second)
        // read the responseChan from the requestChan
        fmt.Println("		goroutineD wait to get response chan.")
        responseChan := <-requestChan
        fmt.Println("		goroutineD has gotten response chan.")
        fmt.Println("		goroutineD sleep 5 minutes.")
        time.Sleep(5 * time.Second)
        // send a value down the responseChan
        fmt.Println("		goroutineD send wassup.")
        responseChan <- "wassup!"
    
        /////Send again to check if response chan dissapear///////////////
        fmt.Println("		goroutineD sleep 5 minutes.")
        time.Sleep(5 * time.Second)
        // send a value down the responseChan
        fmt.Println("		goroutineD send w22222222222.")
        responseChan <- "w22222222222!"
    
    }
    执行结果:
    goroutineC create response chan.
            goroutineD wait to get response chan.
            goroutineD has gotten response chan.
            goroutineD sleep 5 minutes.
    goroutineC waiting to read.
            goroutineD send wassup.
            goroutineD sleep 5 minutes.
    goroutineC get Response:  wassup!
            goroutineD send wassup.
    goroutineC get Response:  w22222222222!

    参考:http://tleyden.github.io/blog/2013/11/23/understanding-chan-chans-in-go/

     https://www.goin5minutes.com/blog/channel_over_channel/

    Visual time lapse walkthrough

    Keep in mind that Goroutine C is the “real consumer” even though it will be the one which writes to the request channel.

    The request channel starts out empty.

    Screenshot

    Goroutine C passes a “response channel” to go routine D via the request channel

    Screenshot

    Goroutine C starts reading from the (still empty) response channel.

    Screenshot

    Goroutine D writes a string to the response channel

    Screenshot

    Goroutine C now is able to read a value from response channel, and get’s the “wassup!” message

    Screenshot

    And now we are back to where we started

    Screenshot

  • 相关阅读:
    python3获取文件夹大小
    git master分支被污染,dev是最新稳定的
    优化经验杂记
    kong
    prometheus
    C# 线程执行带参方法的几种写法(ThreadStart,delegate (),()=>)
    MySql字符集utf8mb4和utf8区别
    程序员必备的一些数学基础知识
    hbase统计表的行数的三种方法
    Flink实时计算pv、uv的几种方法
  • 原文地址:https://www.cnblogs.com/bigben0123/p/8668309.html
Copyright © 2011-2022 走看看