go语言进阶——并发编程

64 阅读2分钟

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

go语言进阶、依赖管理、项目实战(上)——并发编程

并发编程

01协程

协程:用户态,轻量级线程,栈MB级别。

线程:内核态,线程跑多个协程,栈KB级别。

image.png

02 用go关键字 开启协程

如果我们想快速打印hello goroutine : 0~hello goroutine : 4 的话,就可以开启协程来加快速度。 image.png

03通信共享内存

我们提倡通过通信共享内存而不是通过共享内存而实现通信

image.png

04 有缓冲通道的channel类比“生产者消费者”模式

make(chan元素类型,[缓冲大小])

  • 无缓冲通道 make(chan int)
  • 有缓冲通道 make(chan int,2)

image.png

05 channel实例

  1. A协程将生产的数字发送到src这个channel下,
  2. B协程通过for range来遍历src里面的数据,并发送到带缓冲区的dest这个channel下,
  3. 通过src这个channel就实现了A协程和B协程的通信,(用defer进行资源关闭),
  4. 可以看到src和dest之间的传递是能够保证顺序性的,即:是“并发安全”的。

image.png

06 并发安全 Lock

  1. 但是实际情况下,可能会存在多个协程来操作一块共同的内存资源的情况(如右图)
  2. 为了保证并发安全的情况,我们需要对关键代码进行加锁,计算完毕后再将临界区的权限释放掉(解锁)

image.png

WaitGroup

  1. 刚才一直是用的sleep来进行阻塞,这并非是一种优雅的处理。
  2. wait内部是维护了一个计数器,
  3. 如果我们要启动n个并发任务的话,我们可以将计数器add(n),在每个任务完成时,通过调用done()方法,将计数器减一,最后用wait()方法来阻塞,等待所有并发任务执行完毕(即计数器的值为0)。

image.png 下面我们就用waitgroup来对刚才的代码进行优化(上旧 下新)

image.png image.png


并发编程这块就暂时记录这么多吧,内容不多,仔细想想问题不大~