人是一种高并发的物种,细品。 初识 对 Go 语言的第一印象就是其原生地支持并发编程,而且使用的是协程,比线程更加轻量。 关于进程、线程和协程的区别 进程是“程序执行的一个实例” ,担当。..

人是一种高并发的物种,细品。
一、Golang并发编程实践
1.1 初识
刚开始接触 Go 语言的时候,最吸引人的就是它原生支持并发编程,而且用的是协程,比线程轻量多了。
关于进程、线程和协程的区别
简单来说,进程是”程序执行的一个实例”,负责分配系统资源。创建进程需要分配完整的独立地址空间,进程切换只在内核态进行。
线程是进程的一个执行流,独立执行自己的程序代码,是程序执行流的最小单元,也是处理器调度和分派的基本单位。一个进程可以有一个或多个线程。
协程不是进程或线程,执行过程更像子例程,或者说是不带返回值的函数调用。在语言级别可以创建并发协程,然后编写代码进行管理。Go 把这一步承包了,让协程并发运行成本更低。
Go 实现最简单的并发
1 | for i := 0; i < 10; i++ { |
1.2 项目实践
最近在项目中遇到一个需求:需要同时调用多个 job,并且要等所有 job 完成之后才能继续往下执行。
串行执行 job
最开始的做法很简单,就是串行执行所有的 job:
1 | func buildJob(name string) { |
并行执行 job
既然所有 job 可以并发执行,那就不用等上一个 job 完成再执行下一个了。用 Go 的关键字go
就能快速启动一个goroutine
,下面并发执行三个 job:
1 | go buildJob("A") |
1 |
|
来检查执行结果:
func buildJob(ch chan error, name string) {
var err error
... // build job
ch <- err // finnaly, send the result into channel
}
func build() error {
jobCount := 3
errCh := make(err chan error, jobCount)
defer close(errCh) // 关闭 channel
go buildJob(errCh, "A")
go buildJob(errCh, "B")
go buildJob(errCh, "C")
for {
select {
case err := <-ch:
if err != nil {
return err
}
jobCount--
if jobCount <= 0 {
break
}
return nil
}
1 |
|
方法会 return err 退出,并执行 close(errCh) 。但此时另外两个 job B 和 C 可能还在执行,它们也会把结果发给
1 | `errCh` |
if _, ok := <-ch; !ok {
1 | return |
for {
1 | } |
1.3 总结
Go 并发编程看起来很简单,一个关键字go
就能启动一个
1 | ,但实际用起来还是有不少坑要踩的。 |
本文标题: Golang并发编程实践
发布时间: 2021年02月13日 00:00
最后更新: 2025年12月30日 08:54
原始链接: https://haoxiang.eu.org/54c0f351/
版权声明: 本文著作权归作者所有,均采用CC BY-NC-SA 4.0许可协议,转载请注明出处!

