这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
前言
参与青训营课程的学习,我将课程中自己比较有收获的东西进行了整理和总结,用以日后复习和查阅,如果对各位读者有帮助,实属我的荣幸,也希望大家能够不吝赐教,指出我学习中存在的问题,多多交流。
关于Go的并发
并发的概念
在学习操作系统这门课程的过程中,仅强调了并发的一些知识,但在如今CPU多核的硬件条件下,使用并行将性能发挥到极致也是我们需要掌握的,而go语言高性能的原因,其中之一就体现在这个并发性上面
协程Goroutine
- 众所周知,线程是CPU调度和分配的基本单位,被操作系统内核所管理,运行在内核态;
- 而协程是一种比线程更加轻量级的存在,并且完全由程序所控制。
通道Channel
- 通道可以理解成一个对信息进行传输的工具
- 有缓冲通道相对于无缓冲通道的一大优势是:当通道双方的收发速度不一致时,缓冲通道可以一定程度避免因为一方的速度慢导致的整个速度降低,可以更“快”
并发安全Lock
package concurrence
import (
"sync"
"time"
)
var (
x int64
lock sync.Mutex
)
/*
测试使用lock和不使用lock对并发程序结果的影响
*/
func addWithLock() {
for i := 0; i < 2000; i++ {
lock.Lock()
x += 1
lock.Unlock()
}
}
func addWithoutLock() {
for i := 0; i < 2000; i++ {
x += 1
}
}
func Add() {
x = 0
for i := 0; i < 5; i++ {
go addWithoutLock()
}
time.Sleep(time.Second)
println("WithoutLock:", x)
x = 0
for i := 0; i < 5; i++ {
go addWithLock()
}
time.Sleep(time.Second)
println("WithLock:", x)
}
/*
output:
第一次
=== RUN TestAddLock
WithoutLock: 8882
WithLock: 10000
--- PASS: TestAddLock (2.01s)
多次运行后:???
=== RUN TestAddLock
WithoutLock: 10000
WithLock: 10000
--- PASS: TestAddLock (2.02s)
*/
- 而令我疑惑的是,为什么在多次运行测试代码后,有lock和无lock两者的结果一致了?