GoLang的并发编程(第一阶段)| 青训营笔记

111 阅读5分钟

并行与并发

  • 并行

并行是指在同一时刻,有多条指令在多个CPU处理器上同时执行,需要有硬件支持;

并发是指在同一时刻,只有一条指令可以执行,但多个线程指令可以被快速地轮换执行,通俗地讲就是在宏观上在一个特别微小的时间段上,可以执行多条指令,让我们认为就是多条指令在同时执行,但是微观上还是一个时刻只能执行一条指令。

GOLang并发优势

  • go从语言层面就支持了并发,通过goroutine可以轻松实现并发编程
  • 简化了并发程序的编写

进程、线程、协程

  • 进程

学过操作系统的小伙伴们,可能对于进程的概念,第一直觉就是:进程是CPU资源分配的最小单位。

进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。进程是一种抽象的概念,从来没有统一的标准定义。

  • 线程

线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元(cpu调度的最小单位),是处理器调度和分派的基本单位。一个进程可以有一个或多个线程各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成。

  • 协程

协程,英文Coroutines,是一种基于线程之上,但又比线程更加轻量级的存在(用户态的轻量级线程),这种由程序员自己写程序来管理的轻量级线程叫做『用户空间线程』,具有对内核来说不可见的特性。因为是自主开辟的异步任务,所以很多人也更喜欢叫它们纤程(Fiber),或者绿色线程(GreenThread)。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。

协程的特点

  1. 线程的切换由操作系统负责调度,协程由用户自己进行调度,因此减少了上下文切换,提高了效率
  2. 线程的默认Stack大小是1M,而协程更轻量,接近1K。因此可以在相同的内存中开启更多的协程
  3. 由于在同一个线程上,因此可以避免竞争关系而使用锁
  4. 适用于被阻塞的,且需要大量并发的场景。但不适用于大量计算的多线程,遇到此种情况,更好实用线程去解决。

协程的原理

当出现IO阻塞的时候,由协程的调度器进行调度,通过将数据流立刻yield掉(主动让出),并且记录当前栈上的数据,阻塞完后立刻再通过线程恢复栈,并把阻塞的结果放到这个线程上去跑,这样看上去好像跟写同步代码没有任何差别,这整个流程可以称为coroutine,而跑在由coroutine负责调度的线程称为Fiber。比如Golang里的 go关键字其实就是负责开启一个Fiber,让func逻辑跑在上面。

由于协程的暂停完全由程序控制,发生在用户态上;而线程的阻塞状态是由操作系统内核来进行切换,发生在内核态上。 因此,协程的开销远远小于线程的开销,也就没有了ContextSwitch上的开销。

协程和线程的比较

比较项线程协程
占用资源初始单位为1MB,固定不可变初始一般为 2KB,可随需要而增大
调度所属由 OS 的内核完成由用户完成
切换开销涉及模式切换(从用户态切换到内核态)、16个寄存器、PC、SP...等寄存器的刷新等只有三个寄存器的值修改 - PC / SP / DX.
性能问题资源占用太高,频繁创建销毁会带来严重的性能问题资源占用小,不会带来严重的性能问题
数据同步需要用锁等机制确保数据的一直性和可见性不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。

Goroutine

使用协程

go funcName(arg... any)
  • 通过创建多个线程来打印数字
func main() {
    for i := 0; i < 10; i++ {
       go func(j int) {
          fmt.Println("printNum: ", j)
       }(i)
    }
    // 控制主线程执行时间
    time.Sleep(time.Second * 3)
}

注意这里设置的睡眠时间,在真实开发中,我们并不应该使用这种方式来控制主线程的执行时长,这里作为demo,只是单独进行测试而已。

引用文章

最后

笔者是第一次真正去接触有关并发编程的内容,对很多知识都还不是特别了解,然后个人一般习惯于网上查资料的学习方式,喜欢去看别人发的文章,去了解这些技术,目前只是大致了解一下关于go语言的并发编程,在视频学习中,我也了解到go实现并发编程的方式也有多种,当然,其中的协程当属是go的独家秘方,作为它的特色,我也会进一步地学习。