Go语言进阶之并发编程|青训营笔记

30 阅读3分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 4 天

并发程序是指同时执行多个任务的程序,绝大多数的高级语言均支持并发编程,本文将重点学习go语言中的并发运行机制。

基础概念

并发和并行

  • 并发:两个或多个事件在同一时间间隔发生,是同一实体上的多个事件(在同一个处理器上“同时”处理多个任务),并发是一种由于切换间隔短而产生的“同时发生”的错觉,实际上并不是同时。
  • 并行:两个或多个事件在同一时刻发生,是在不同实体上的多个事件(在不同处理器上同时处理多个任务。

进程和线程

  • 进程:程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。
  • 线程:进程的一个执行实体,是CPU调度和分派的基本点位,是比进程更下的能独立运行的基本单位。
  • 一个进程可以创建和撤销多个线程,同一个进程中的多个线程之间可以并发执行。

协程和线程

  • 协程:独立的栈空间,共享堆空间,调度由用户自己控制,本质上有点类似于用户级线程,这些用户级线程的调度也是自己实现的。
  • 线程:一个线程上可以跑多个线程,协程是轻量级的线程。

Goroutine

在go语言中,每一个并发的执行单元叫做一个goroutine。goroutine 是一种非常轻量级的实现,可在单个进程里执行成千上万的并发任务,它是Go语言并发设计的核心。 goroutine 其实就相当于线程,但是它比线程更小,十几个 goroutine 可能体现在底层就是五六个线程,而且go语言内部也实现了 goroutine 之间的内存共享。

当一个程序启动时,其主函数在一个单独的goroutine上运行,被称作main goroutine,新的goroutine则用go语句来创建。

//go 关键字放在方法调用前新建一个 goroutine 并执行方法体
go GetThingDone(param1, param2);
//新建一个匿名方法并执行
go func(param1, param2) {
}(val1, val2)
//直接新建一个 goroutine 并在 goroutine 中执行代码块
go {
    //do someting...
}

Channel

channel是go语言在语言级别提供的goroutine间的通信方式,可以使用channel在两个或多个goroutine之间传递消息。

channel 是进程内的通信方式,因此通过 channel 传递对象的过程和调用函数时的参数传递行为比较一致,比如也可以传递指针等。channel 是类型相关的,也就是说,一个 channel 只能传递一种类型的值,这个类型需要在声明 channel 时指定。

定义

ch = make(chan int)    // unbuffered channel
ch = make(chan int, 0) // unbuffered channel
ch = make(chan int, 3) // buffered channel with capacity 3

使用

ch <- x  // a send statement
x = <-ch // a receive expression in an assignment statement
<-ch     // a receive statement; result is discarded

总结

go语言的并发编程主要通过goroutine实现,channel提供了goroutine间通信的方式,在程序中应用并发可以充分利用CPU核心的优势,提高程序的执行效率。