zoukankan      html  css  js  c++  java
  • Golang并发编程进程通信channel了解及简单使用

    概念及作用

    channel是一个数据类型,用于实现同步,用于两个协程之间交换数据。goroutine奉行通过通信来共享内存,而不是共享内存来通信。
    引用类型channel是CSP模式的具体实现,用于多个goroutine通讯。其内部实现了同步,确保并发安全。

    创建及使用
    每个channel在创建的时候必须指定一个类型,指定的类型是任意的。

    ch := make(chan int)   //使用内置的make函数,可以创建一个channel类型
    // 发送数据到channel
    ch <- 1
    // 从channel接受数据
    x := <- ch

    案例举例(一)

    ①创建channel前

    package main
    
    import (
        "fmt"
        "time"
    )
    
    //定义一个打印机,参数为字符串,按每个字符打印
    //打印机属于公共资源
    func Printer(str string) {
        for _, data := range str {
            fmt.Printf("%c", data)
            time.Sleep(time.Second)
        }
        fmt.Printf("
    ")
    }
    
    func person1() {
        Printer("hello")
    }
    
    func person2() {
        Printer("world")
    }
    
    func main() {
        //新建2个协程,代表2个人,2个人同时使用打印机
        go person1()
        go person2()
    
        //特地不让主协程结束,死循环
        for {
    
        }
    }
    //结果
    hwoerllldo   //交叉执行

    ②创建channel后(注意channel变量和调用的先后顺序)

    package main
    
    import (
        "fmt"
        "time"
    )
    
    //全局变量,创建一个channel
    var ch = make(chan int)
    
    //定义一个打印机,参数为字符串,按每个字符打印
    //打印机属于公共资源
    func Printer(str string) {
        for _, data := range str {
            fmt.Printf("%c", data)
            time.Sleep(time.Second)
        }
        fmt.Printf("
    ")
    }
    
    //person1执行完后,才能到person2执行
    func person1() {
        Printer("hello")
        ch <- 666 //给管道写数据,发送
    }
    
    func person2() {
        <-ch //从管道取数据,接收,如果通道没有数据他就会阻塞
        Printer("world")
    }
    
    func main() {
        //新建2个协程,代表2个人,2个人同时使用打印机
        go person1()
        go person2()
    
        //特地不让主协程结束,死循环
        for {
    
        }
    }
    hello
    world

    案例举例(二)

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        ch := make(chan string)
        go func() {
            fmt.Println("aaaaaaaaaa")
            str := <-ch // 在执行到这一步的时候main goroutine才会停止阻塞
            fmt.Println("取出channel的数据" + str)
        }()
        fmt.Println("bbbbbbbbbb")
        ch <- "hello" // 如果没有其他goroutine来取走这个数据,main goroutine挂起,直到其它gorouteine把数据拿走(这里会暂时阻塞)
        fmt.Println("cccccccccc")
    }
    bbbbbbbbbb
    aaaaaaaaaa
    取出channel的数据hello
    cccccccccc
  • 相关阅读:
    字节跳动2020年九月笔试题-爬楼梯(不能连续爬两个两步)
    c/c++经典面试题-part1
    C++单例模式之一见钟情
    多线程同步的四种方式(史上最详细+用例)
    c++多态之动态绑定
    Redis从入门到入坑
    编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串 是由同一字符组成的。
    面试之进制转换函数
    c++编程题之空调遥控器
    static 和 const关键字的作用
  • 原文地址:https://www.cnblogs.com/wt645631686/p/9656783.html
Copyright © 2011-2022 走看看