当前位置:网站首页>Golang Mutex
Golang Mutex
2022-08-03 13:14:00 【Cloud full of notes】
1. Golang 互斥锁
1.1. 基础知识
To write lock and unlock, 简称"写锁定"和"写解锁":
func (*RWMutex) Lock()
func (*RWMutex) Unlock()
To read lock and unlock, 简称为"读锁定"与"读解锁":
func (*RWMutex) RLock()
func (*RWMutex) RUnlock()
Don't think a use lock sample:
func printer(str string) {
for _, data := range str {
fmt.Printf("%c", data)
}
fmt.Println()
}
func person1() {
printer("hello")
}
func person2() {
printer("world")
}
func main() {
go person1()
person2()
time.Sleep(time.Second)
} //输出结果//worhello//ld
Add a mutex sample:
var mut sync.Mutex
func printer(str string) {
mut.Lock()
defer mut.Unlock()
for _, data := range str {
fmt.Printf("%c", data)
}
fmt.Println()
}
func person1() {
printer("hello")
}
func person2() {
printer("world")
}
func main() {
go person1()
person2()
time.Sleep(time.Second)
} //输出结果//world//hello
1.2. 注意事项
1.2.1. 互斥锁
- 不要重复锁定互斥锁: 对一个已经被锁定的互斥锁进行锁定, 是会立即阻塞当前的 goroutine, 这个 goroutine 所执行的流程, 会一直停滞在调用该互斥锁的 Lock 方法的那行代码上.(注意: 这种由 Go 语言运行时系统自行抛出的 panic 都属于致命错误, 都是无法被恢复的, 调用 recover 函数对它们起不到任何作用.也就是说, 一旦产生死锁, 程序必然崩溃.)
- 不要忘记解锁互斥锁, 必要时使用 defer 语句: 因为在一个 goroutine 执行的流程中, 可能会出现诸如"锁定、解锁、再锁定、再解锁"的操作, 所以如果我们忘记了中间的解锁操作, 那就一定会造成重复锁定.
var mutex sync.Mutex
func write() {
defer mutex.Unlock() // 通过 defer 解锁
mutex.Lock() // 获取临界资源, 执行具体逻辑...
}
- Don't take has yet to lock or unlock the mutex unlock: This program will directly panic.
var mutex sync.Mutex // 定义互斥锁变量 mutex
func main() {
mutex.Lock()
mutex.Unlock()
mutex.Unlock() // fatal error: sync: unlock of unlocked mutexreturn
}
- 不要在多个函数之间直接传递互斥锁: A mutex is a structure type, 即值类型, 把它传给一个函数、将它从函数中返回、把它赋给其他变量、Make it into a channel will lead to a copy of it.因此, 原值和它的副本、以及多个副本之间都是完全独立的, 它们都是不同的互斥锁.
1.2.2. 读写锁
- 在写锁已被锁定的情况下再试图锁定写锁, 会阻塞当前的 goroutine;
- 在写锁已被锁定的情况下试图锁定读锁, 也会阻塞当前的 goroutine;
- 在读锁已被锁定的情况下试图锁定写锁, 同样会阻塞当前的 goroutine;
- 在读锁已被锁定的情况下再试图锁定读锁, 并不会阻塞当前的 goroutine;
- 解锁"Not be locked in read-write lock write lock", 会立即引发 panic, So to read lock.
Write a little verbose, I use a word to summarize: When I read the data, You can go to read, Because I two data is the same; When I read the data, 你不能写, 你写了, 数据就变了, I also read a ghost; When I write, 你不能读, 也不能写, I am so strong.下面看一个实例:
var count int
var mutex sync.RWMutex
func write(n int) {
rand.Seed(time.Now().UnixNano())
fmt.Printf("写 goroutine %d 正在写数据...\n", n)
mutex.Lock()
num := rand.Intn(500)
count = num
fmt.Printf("写 goroutine %d 写数据结束, 写入新值 %d\n", n, num)
mutex.Unlock()
}
func read(n int) {
mutex.RLock()
fmt.Printf("读 goroutine %d 正在读取数据...\n", n)
num := count
fmt.Printf("读 goroutine %d 读取数据结束, 读到 %d\n", n, num)
mutex.RUnlock()
}
func main() {
for i := 0; i < 10; i++ {
go read(i + 1)
}
for i := 0; i < 10; i++ {
go write(i + 1)
}
time.Sleep(time.Second * 5)
}
输出结果:
读 goroutine 1 正在读取数据...
读 goroutine 1 读取数据结束, 读到 0
读 goroutine 7 正在读取数据...
读 goroutine 7 读取数据结束, 读到 0
读 goroutine 3 正在读取数据...
读 goroutine 3 读取数据结束, 读到 0
读 goroutine 10 正在读取数据...
读 goroutine 10 读取数据结束, 读到 0
读 goroutine 8 正在读取数据...
读 goroutine 8 读取数据结束, 读到 0
读 goroutine 6 正在读取数据...
读 goroutine 5 正在读取数据...
读 goroutine 5 读取数据结束, 读到 0
写 goroutine 2 正在写数据...
读 goroutine 4 正在读取数据...
读 goroutine 4 读取数据结束, 读到 0
写 goroutine 4 正在写数据...
写 goroutine 3 正在写数据...
读 goroutine 2 正在读取数据...
读 goroutine 2 读取数据结束, 读到 0
写 goroutine 9 正在写数据...
读 goroutine 6 读取数据结束, 读到 0
写 goroutine 7 正在写数据...
读 goroutine 9 正在读取数据...
读 goroutine 9 读取数据结束, 读到 0
写 goroutine 6 正在写数据...
写 goroutine 1 正在写数据...
写 goroutine 8 正在写数据...
写 goroutine 10 正在写数据...
写 goroutine 5 正在写数据...
写 goroutine 2 写数据结束, 写入新值 365
写 goroutine 4 写数据结束, 写入新值 47
写 goroutine 3 写数据结束, 写入新值 468
写 goroutine 9 写数据结束, 写入新值 155
写 goroutine 7 写数据结束, 写入新值 112
写 goroutine 6 写数据结束, 写入新值 490
写 goroutine 1 写数据结束, 写入新值 262
写 goroutine 8 写数据结束, 写入新值 325
写 goroutine 10 写数据结束, 写入新值 103
写 goroutine 5 写数据结束, 写入新值 353
可以看出前面 10 Collaborators process can be read in parallel data, 后面 10 个协程, Is blocked in the"… 正在写数据.…"过程, Such as reading, 然后 10 Collaborators began to write in turn cheng.
1.3. 总结
The content of this chapter is not much, Need to pay attention to the mutex and read-write lock several matters needing attention, Read-write lock is more granular lock division, In order to make better applications of concurrent, It has been very clear about, 这里就不再啰嗦.The only stressed the point again, Whether a mutex or read-write lock, We all don't try to unlock the lock unlocked, Because it will cause irreversible panic.
边栏推荐
- Image fusion GAN-FM study notes
- 超多精美礼品等你来拿!2022年中国混沌工程调查启动
- VLAN 实验
- 7月份最后一篇博客
- YOLOv5 training data prompts No labels found, with_suffix is used, WARNING: Ignoring corrupted image and/or label appears during yolov5 training
- An introduction to 3D tools
- The components of the basis of An animation movie clip animation between traditional filling
- Nodejs 安装依赖cpnm时,install 出现Error: Cannot find module ‘fs/promises‘
- 图像融合GAN-FM学习笔记
- 海外代购系统/代购网站怎么搭建——源码解析
猜你喜欢

Key points for account opening of futures companies

An introduction to the skeleton tool

漫画:怎么证明sleep不释放锁,而wait释放锁?

论文理解:“Gradient-enhanced physics-informed neural networks for forwardand inverse PDE problems“

An工具介绍之宽度工具、变形工具与套索工具

【蓝桥杯选拔赛真题48】Scratch跳舞机游戏 少儿编程scratch蓝桥杯选拔赛真题讲解

期货公司开户关注的关键点

An工具介绍之3D工具

Win11怎么禁止软件后台运行?Win11系统禁止应用在后台运行的方法

Classes and objects (upper)
随机推荐
ECCV 2022|通往数据高效的Transformer目标检测器
PyTorch构建分类网络模型(Mnist数据集,全连接神经网络)
[数据仓库]分层概念,ODS,DM,DWD,DWS,DIM的概念「建议收藏」
Image fusion GAN-FM study notes
[Blue Bridge Cup Trial Question 48] Scratch Dance Machine Game Children's Programming Scratch Blue Bridge Cup Trial Question Explanation
The new interface, jingdong comment interface
【深度学习】高效轻量级语义分割综述
业界新标杆!阿里开源自研高并发编程核心笔记(2022最新版)
Grafana 高可用部署最佳实践
便携烙铁开源系统IronOS,支持多款便携DC, QC, PD供电烙铁,支持所有智能烙铁标准功能
Win11怎么禁止软件后台运行?Win11系统禁止应用在后台运行的方法
Classes and Objects (lower middle)
类和对象(中上)
Jmeter使用
Using the Work Queue Manager (4)
Last blog for July
Station B responded that "HR said that core users are all Loser": the interviewer was persuaded to quit at the end of last year and will learn lessons to strengthen management
How does Filebeat maintain file state?
BOM系列之sessionStorage
期货公司开户关注的关键点