美文网首页
26.Go语言·管道Channel

26.Go语言·管道Channel

作者: 一枼落知天下 | 来源:发表于2019-06-11 19:35 被阅读0次

    main.go

    // Go语言·管道Channel
    package main
    
    
    import (
        model "day31/model"
    )
    
    var content string = `
    ————————————————Go语言·管道Channel————————————————————
    一、协程&管道
        1.全局变量加锁[互斥锁],同步改进程序
            sync包提供了基本的同步基元,
            如互斥锁。除了Once和WaitGroup类型,
            大部分都是适用于低水平程序线程,
            高水平的同步使用channel通信更好一些。
    二、管道Channel
        1.就是一个数据结构-队列
        2.数据先进先出 [FIFO,first in first out]
        3.线程安全,多个goroutine访问时,不需要加锁,
        不会产生资源竞争问题
        channel本身就是线程安全的
        4.channel有类型的
    三、管道基本使用
        var 变量名 chan 数据类型
        var intChan chan int 
        var mapChan chan map[int][string]
        var perChan chan Person
        var perChan2 chan *Person
        管道是引用类型
        管道必须初始化才能写入数据,即make后才能使用
        管道是有类型的 intChan只能写入整数int
    四、注意事项:
        1.只能放指定类型的数据
        2.管道数据存满咯,不能继续放了(不能超过管道容量)
        3.从管道中取出数据后,可以继续放入
        4.在没有使用协程的情况下,如果管道数据取完了,再取,就会报dead lock
        5.chan interface{} 需要类型断言interface--》Cat数据类型 
            比如:mycat.(Cat)
    五、管道的遍历和关闭
        1.使用内置函数close,一旦关闭就不能写入数据,只能读取
        2.支持for-range的方式进行遍历:
            a.遍历时,管道没有关闭,就会出现错误:
                fatal error: all goroutines are asleep - deadlock!
            b.遍历时,管道已经关闭,则会正常遍历,遍历完后,就会退出遍历
    六、协程&管道双剑合璧
    `
    
    
    
    
    func main() {
        model.Test()
    }
    

    model/Channel.go

    package model
    
    import (
        "fmt"
    )
    
    type Cat struct {
        Name string
        Age  int
    }
    
    /*
        管道是引用类型
        管道必须初始化才能写入数据,即make后才能使用
        管道是有类型的 intChan只能写入整数int
    */
    func Test() {
        // 声明一个管道
        var intChan chan int
        // 初始化
        intChan = make(chan int, 3)
        // intChan的值:0xc00009c080,intChan本身的地址:0xc000096018
        fmt.Printf("intChan的值:%v,intChan本身的地址:%p \n",
            intChan, &intChan)
    
        // 向管道写入数据
        // 输入数据时,不能超过管道容量
        intChan <- 10
        num := 112
        intChan <- num
        intChan <- 98
        // 看管道容量,长度
        // intChan的长度:2,intChan本身的容量:3
        fmt.Printf("intChan的长度:%v,intChan本身的容量:%v \n",
            len(intChan), cap(intChan))
    
        // 从管道中读取数据
        // 读取数据时,也不能超过管道容量
        var num2 int
    
        num2 = <-intChan
        // num2= 10
        fmt.Println("num2=", num2)
        // intChan的长度:2,intChan本身的容量:3
        fmt.Printf("intChan的长度:%v,intChan本身的容量:%v \n",
            len(intChan), cap(intChan))
    }
    
    /**
     * [MiaoCat 任何数据类型的管道]
     * @author Jhou Shuai
     * @datetime 2019-06-11T16:24:59+0800
     */
    func MiaoCat() {
        var allChan chan interface{}
        allChan = make(chan interface{}, 3)
    
        allChan <- 10
        allChan <- "ZhouShuai"
        cat := Cat{"小喵喵", 4}
        allChan <- cat
        <-allChan
        <-allChan
        mycat := <-allChan
    
        fmt.Printf("内容:%v,类型:%T \n", mycat, mycat)
        // 下面的写法是错误的,编译不通过
        // mycat.Name undefined (type interface {}
        // is interface with no methods)
        // fmt.Printf("mycat.Name = %v \n",mycat.Name)
        // 类型断言interface--》Cat类型 mycat.(Cat)
        fmt.Printf("mycat.Name = %v \n", mycat.(Cat).Name)
    }
    
    /**
     * [CloseChannel 管道的关闭]
     * @author Jhou Shuai
     * @datetime 2019-06-11T16:37:06+0800
     */
    func CloseChannel() {
        intChan := make(chan int, 3)
        intChan <- 100
        intChan <- 10
        // 内建函数close关闭管道
        close(intChan)
        // intChan<-23  //panic: send on closed channel
        num1 := <-intChan
        fmt.Println("num1=", num1)
    }
    
    func ForRangeChannel() {
        intchan := make(chan int, 100)
        for i := 0; i < 100; i++ {
            intchan <- i * 2
        }
    
        close(intchan)
    
        for val := range intchan {
            fmt.Println(val)
        }
    }
    
    

    相关文章

      网友评论

          本文标题:26.Go语言·管道Channel

          本文链接:https://www.haomeiwen.com/subject/mmscfctx.html