Go routine 协程
协程和通道,是 Go 语言并发的基础。谈并发,就绕不开线程,操作系统会为 deamon 服务创建进程,进程可以看作一个服务的工作空间,它包含了服务运行所需的所有资源(PCB控制块),比如内存空间、文件句柄等。线程是进程的执行空间,一个进程可以有多个线程,线程被操作系统调度执行,也就是可以实现多线程的并发。
Go 中的并发,是通过协程 goroutine 来实现的。相比线程来说,协程更加轻量,一个程序可以随意开启成千上万个 goroutine。协程是被 Go 运行时所调度的,这一点和线程不同。对开发者来说完全透明,只需要编码的时候告诉 Go 语言,要启动几个协程,什么时候执行哪几个,至于如何调度,如何执行,这些都不用关心。如果想深入了解,就去看 GMP 调度模型的源码。
启动一个协程非常简单,Go语言提供了 go 关键字。下面这段代码里启动了一个协程,调用 Println 函数打印,一个是 main 函数启动的 main 协程,一个是通过 go 关键字启动的协程。
package main
import (
"fmt"
"time"
)
func main() {
go fmt.Println("This is a go routine")
fmt.Println("This is a main routine")
time.Sleep(time.Second)
}
Go 关键字的语法,方法 function() 在新启动的协程中运行。
go function()
运行结果如下,可以看出,程序是并发的,go启动的协程并不会阻塞main的协程。上面 Sleep 函数是等待1秒,让整个 main 协程等待1秒,不然 main 函数就整个退出了,也就看不到新协程的打印输出了。后面会使用 channel 、WaitGroup来实现这一同步的功能。
如果启动了多个 goroutine,它们之间该如何通信,或者保持同步呢?现在存在俩问题,无法有效的并发执行完成,无法有效的控制并发。
Go语言提供了通道channel、同步原语sync和context上下文来解决上面的这个问题,也就是说提供了控制并发的三种方式,可以用这些基础元素组成好用的并发模式。
通道 Channel
Go channel 通道_Schuyler_yuan的博客-CSDN博客
同步原语 Sync
Go sync 同步原语_Schuyler_yuan的博客-CSDN博客
上下文 Context
Go Context 上下文_Schuyler_yuan的博客-CSDN博客
好用的并发模式
Golang同步和异步执行_谱写的博客-CSDN博客_golang异步任务
Golang并发编程-Channel的使用场景分析_pbrong的博客-CSDN博客_channel的应用场景
Go channel的使用场景与注意项_浩骞的博客-CSDN博客
盘点Go并发那些事儿之二-GO并发控制得心应手-云社区-华为云
Have Fun