开发者-导航 猿导航

go goroutine (协程) 到底是什么

发布时间:

概念 #

官方内容 #

为什么使用 goroutines 而不是线程?

goroutines 是使并发易于使用的一部分。这个想法已经存在了一段时间,就是将独立执行的函数(协程)多路复用到一组线程上。当协程阻塞时(例如通过调用阻塞系统调用),运行时会自动将同一操作系统线程上的其他协程移动到不同的可运行线程,这样它们就不会被阻塞。程序员看不到这些,这就是重点。结果,我们称之为 goroutines,可以非常便宜:除了堆栈内存(只有几千字节)之外,它们几乎没有开销。

为了使堆栈变小,Go 的运行时使用可调整大小的有界堆栈。新创建的 goroutine 被分配几千字节,这几乎总是足够的。当它不够时,运行时会自动增加(和缩小)用于存储堆栈的内存,从而允许许多 goroutine 驻留在适量的内存中。CPU 开销平均每个函数调用大约三个廉价指令。在同一个地址空间中创建数十万个 goroutine 是可行的。如果 goroutine 只是线程,系统资源耗尽的数量就会少得多。

结论一个进程有多个线程(板上钉钉),一个线程有多个协程(个人结论),所以它不是线程而是协程。

协程通信 #

c:= make(chan struct{})
go func() {
	fmt.Println(111)
	time.Sleep(10 * time.Millisecond)
	c<- struct{}{}
	fmt.Println(222)
}()
<-c
fmt.Println(333)

输出

111
333
222

通信操作符号 <- #

简单理解,c 在 <- 前发送,c 在 <- 后接收,c 创建的通道名称

发送数据

c<- struct{}{}

接收数据

<-c