美文网首页
Go语言基础——goroutine和channel

Go语言基础——goroutine和channel

作者: 北枫晴天 | 来源:发表于2018-07-15 07:33 被阅读0次

    go语言有一个很重要的特性就是 goroutine, 我们可以使用 goroutine 结合 channel 来开发并发程序。

    1、goroutine简介

    goroutine是go语言中的并发执行单元,我们可以将多个任务分别放在多个 goroutine 中,参见下文案例:

    package main
    
    import "fmt"
    
    func hello() {
        fmt.Println("Hello World!!!")
    }
    func main() {
        go hello()  // 启动goroutine
        fmt.Println("Bye!!!")
    
        var input string
        fmt.Scanln(&input)
    }
    

    多次运行程序结果如下:


    图片.png

    以上栗子中有几点说明:

    • 使用go关键字可以启动一个goroutine运行,go需要加在函数调用名称的前面。
    • main函数也在独立的一个goroutine中运行。
    • 每次执行的输出结果顺序可能是不同的,因为不同的goroutine执行的时间可能不同。

    2、channel简介

    在上个例子中fmt.Scanln(&input)用于阻塞main函数goroutine的运行,知道获得一个输入后,程序终止,主要是为了展示hello函数的运行,否则当程序输出Bye!!!,main程序自动结束,将看不到hello函数的输出。
    go语言提供channel机制给goroutine进行通信:

    (1)channeld的创建
    ch1 := make(chan int)  //创建无缓冲的channel,channel的元素类型为int
    ch2 :=make(chan int, 2)  //创建有缓冲的channel,channel的元素类型为int,容量为2个元素
    

    channel 使用 make 函数来创建,它是一种引用类型。

    (2)向 channel 中读写数据

    通道有两个主要操作:发送(send)和接收(receive),两者统称为通信。
    send语句从一 个goroutine传输一个值到另一个在receive接收表达式的goroutine。
    两个操作都使用 <-操作符书写。发送语句中,通道和值分别在 <-的左右两边。在接收表达式中,<-放在通道操作数前面。在接收表达式中,其结果未被使用也是合法的。

    ch <- x //发送语句到channel
    X = <-ch //赋值语句中的接收表达式 
    <-ch //接收语句,丢弃结果
    
    (3)关闭 channel

    在我们使用完一个 channel 之后,可以调用 close() 方法来关闭一个 channel, 关闭之后的通道,不能够再进行数据的写操作, 但是仍然可以读取之前写入成功的数据(如果没有数据了,将返回零值)。

    close(ch)  //关闭channel
    
    • 无缓冲的 channel 的发送操作将导致发送者的 goroutine 阻塞,直到在另一个 goroutine 上对其进行接收操作。如果先发生的是接收操作,那么接收者将被阻塞,直到在另一个 goroutine 上对其进行发送操作。
    • 带缓存的 channel 可以缓存多个数据,因此不会立即阻塞,只有当缓存满了之后,发送者才可能会被阻塞,并且只有到缓存为空时,接收者才可能被阻塞

    相关文章

      网友评论

          本文标题:Go语言基础——goroutine和channel

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