Go语言进阶|青训营笔记

27 阅读2分钟

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

从并发编程的角度了解go语言的高性能

并发和并行的区别

我们在电脑上可以在打游戏的“同时”听音乐,但在电脑的操作系统里并不是真正意义上的同时

  • 对于单核CPU的计算机来说,在CPU中,同一时间是只能干一件事儿的。
  • 为了看起来像是“同时干多件事”,操作系统是把CPU的时间划分成长短基本相同的时间区间,即”时间片”,通过操作系统的管理,把这些时间片依次轮流地分配给各个应用使用。
  • 操作系统时间片的使用是有规则的:某个作业在时间片结束之时,整个任务还没有完成,那么该作业就被暂停下来,放弃CPU,等待下一轮循环再继续做。此时CPU又分配给另一个作业去使用。

这样,给用户的感觉是他在同时的进行听歌和打游戏,实际上,在操作系统中,CPU是在游戏进程和音乐播放器进程之间来回切换执行的。

并发

并发(Concurrent),在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。

并行

并行(Parallel),当系统有一个以上CPU时,当一个CPU执行一个进程时,另一个CPU可以执行另一个进程,两个进程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。 屏幕截图_20230203_205135.png

线程与协程

协程:即轻量级线程(goroutine),用户态,线程可以跑多个协程,栈是KB级别
线程:内核态,对系统资源的消耗较大,栈是MB级别

屏幕截图_20230203_225249.png 协程大致可以看作与其他协程在同一片内存地址同时运行的一个函数

package main

import (
   "fmt"
   "time"
)

func hello(i int) {
   fmt.Println("hello goroutine:", i)
}
func main() {
   for i := 0; i < 5; i++ {
   //通过go关键字调用协程
      go func(j int) {
         hello(j)
      }(i)
   }
   time.Sleep(time.Second)//保证主线程不结束
}

屏幕截图_20230205_220016.png

我们可以发现打印结果是乱序的,说明调用的协程是并行

CSP

屏幕截图_20230205_220437.png go提倡通过通信共享内存

通道(channel):属于引用类型,对协程进行连接,保证数据的先后

屏幕截图_20230205_222752.png make(chan 元素类型,缓冲大小)

  • 无缓冲通道(同步通道):make(chan int)
  • 缓冲通道:make(chan int,num)