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

  • 相关阅读:
    题解 P2647 【最大收益】
    CF817E Choosing The Commander
    P2922 [USACO08DEC]Secret Message G
    洛谷月赛 P7107 天选之人
    如何在考场上快速用C++写高级对拍器
    题解 CF527D 【Clique Problem】
    P6768 [USACO05MAR]Ombrophobic Bovines 发抖的牛
    [USACO06NOV]Corn Fields G
    Orz 教主的比赛题解
    JZOI 4311 统一天下
  • 原文地址:https://www.cnblogs.com/bigben0123/p/8668309.html
Copyright © 2011-2022 走看看