这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
go语言进阶、依赖管理、项目实战(上)——并发编程
并发编程
01协程
协程:用户态,轻量级线程,栈MB级别。
线程:内核态,线程跑多个协程,栈KB级别。
02 用go关键字 开启协程
如果我们想快速打印hello goroutine : 0~hello goroutine : 4 的话,就可以开启协程来加快速度。
03通信共享内存
我们提倡通过通信共享内存而不是通过共享内存而实现通信
04 有缓冲通道的channel类比“生产者消费者”模式
make(chan元素类型,[缓冲大小])
- 无缓冲通道 make(chan int)
- 有缓冲通道 make(chan int,2)
05 channel实例
- A协程将生产的数字发送到src这个channel下,
- B协程通过for range来遍历src里面的数据,并发送到带缓冲区的dest这个channel下,
- 通过src这个channel就实现了A协程和B协程的通信,(用defer进行资源关闭),
- 可以看到src和dest之间的传递是能够保证顺序性的,即:是“并发安全”的。
06 并发安全 Lock
- 但是实际情况下,可能会存在多个协程来操作一块共同的内存资源的情况(如右图)
- 为了保证并发安全的情况,我们需要对关键代码进行加锁,计算完毕后再将临界区的权限释放掉(解锁)
WaitGroup
- 刚才一直是用的sleep来进行阻塞,这并非是一种优雅的处理。
- wait内部是维护了一个计数器,
- 如果我们要启动n个并发任务的话,我们可以将计数器add(n),在每个任务完成时,通过调用done()方法,将计数器减一,最后用wait()方法来阻塞,等待所有并发任务执行完毕(即计数器的值为0)。
下面我们就用waitgroup来对刚才的代码进行优化(上旧 下新)
并发编程这块就暂时记录这么多吧,内容不多,仔细想想问题不大~