这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
Go语言的并发编程
协程
协程,Goroutines,是一种基于线程之上,但又比线程更加轻量级的存在,具有对内核来说不可见的特性。一个进程可以拥有多个线程一样,一个线程可以拥有多个协程。协程解决的是线程的切换开销和内存开销的问题。
特点:
- 用户空间 首先是在用户空间, 避免内核态和用户态的切换导致的成本。
- 由语言或者框架层调度
- 更小的栈空间允许创建大量实例(百万级别)
1. go
Go 程序会智能地将 goroutine 中的任务合理地分配给每个 CPU。Go 程序从 main 包的 main() 函数开始,在程序启动时,Go 程序就会为 main() 函数创建一个默认的 goroutine。
- func1() 与 func2() 同时执行。
go func1() func2()
2. sync.WaitGroup
Go语言中可以使用sync.WaitGroup来实现并发任务的同步。 sync.WaitGroup有以下几个方法:Add(n)、Done()、Wait()。
sync.WaitGroup内部维护着一个计数器,计数器的值可以增加和减少。
例如当我们启动了N 个并发任务时,就将计数器值增加N。每个任务完成时通过调用Done()方法将计数器减1。通过调用Wait()来等待并发任务执行完,当计数器值为0时,表示所有并发任务已经完成。
3. GOMAXPROCS
Go运行时的调度器使用GOMAXPROCS参数来确定需要使用多少个OS线程来同时执行Go代码。默认值是机器上的CPU核心数。例如在一个8核心的机器上,调度器会把Go代码同时调度到8个OS线程上(GOMAXPROCS是m:n调度中的n)。
Go语言中可以通过runtime.GOMAXPROCS()函数设置当前程序并发时占用的CPU逻辑核心数。