Go语言基础——goroutine和channel - Go语言中文社区

Go语言基础——goroutine和channel


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 可以缓存多个数据,因此不会立即阻塞,只有当缓存满了之后,发送者才可能会被阻塞,并且只有到缓存为空时,接收者才可能被阻塞
版权声明:本文来源简书,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://www.jianshu.com/p/b5b67fbbb43a
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-01-12 12:50:50
  • 阅读 ( 1689 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢