当前位置:网站首页>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.
边栏推荐
- self-discipline
- [Verilog] HDLBits Problem Solution - Circuits/Sequential Logic/Latches and Flip-Flops
- Key points for account opening of futures companies
- Jmeter use
- The Yangtze river commercial Banks to the interview
- How does Filebeat maintain file state?
- Grafana 高可用部署最佳实践
- 论文理解:“Gradient-enhanced physics-informed neural networks for forwardand inverse PDE problems“
- An动画基础之散件动画原理与形状提示点
- From the physical level of the device to the circuit level
猜你喜欢
Jmeter使用
可视化图表设计Cookbook
【实战技能】单片机bootloader的CANFD,I2C,SPI和串口方式更新APP视频教程(2022-08-01)
[R] Use grafify for statistical plotting, ANOVA, intervention comparisons, and more!
VLAN 实验
【R】用grafify搞定统计绘图、方差分析、干预比较等!
Yahoo! Answers-数据集
Oracle is installed (system disk) and transferred from the system disk to the data disk
An introduction to the skeleton tool
期货开户中常见问题汇总
随机推荐
基于php家具销售管理系统获取(php毕业设计)
Autumn recruitment work
Last blog for July
软件测试面试(四)
Golang 通道 channel
setTimeout 、setInterval、requestAnimationFrame
R language ggplot2 visualization: use the patchwork bag plot_layout function will be more visual image together, ncol parameter specifies the number of rows, specify byrow parameters configuration dia
Redis连接池工具类
Five, the function calls
An animation optimization of traditional guide layer animation
From the physical level of the device to the circuit level
8/2 训练日志(dp+思维+字典树)
【深度学习】高效轻量级语义分割综述
链游NFT元宇宙游戏系统开发技术方案及源码
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
php microtime encapsulates the tool class, calculates the running time of the interface (breakpoint)
什么是分布式锁?几种分布式锁分别是怎么实现的?
滑动窗口的最大值
云计算服务主要安全风险及应对措施初探
YOLOv5 training data prompts No labels found, with_suffix is used, WARNING: Ignoring corrupted image and/or label appears during yolov5 training