Golang -- 互斥锁
来源:互联网 发布:服务器对应默认端口 编辑:程序博客网 时间:2024/06/01 16:28
互斥锁 sync.Mutex
sync.Mutex 只有两个公开的指针方法 Lock() 和 Unlock().
Lock() 用于锁定当前互斥量.
Unlock() 用于对互斥量解锁.
- 如果锁定了一个已锁定的互斥锁,则进行重复加锁的goroutine将会阻塞. 当互斥锁解锁后,阻塞的goroutine会唤醒.
演示程序:
package mainimport ( "fmt" "sync" "time")func main() { var mutex sync.Mutex fmt.Println("加锁. (main)") mutex.Lock() fmt.Println("锁上了 (main)") go func() { fmt.Println("加锁 (goroutine)") mutex.Lock() // 对已经加锁的mutex进行重复加锁 fmt.Println("锁上了 (goroutine)") }() time.Sleep(time.Second) fmt.Println("解锁了 (main)") mutex.Unlock() time.Sleep(time.Second) fmt.Println("main exit")}
演示结果:
分析:
1. 首先main线程进行加锁, 加锁后启动了goroutine,main线程睡1秒,保证goroutine运行起来.
2. goroutine启动后, 进行重复加锁操作,导致 goroutine自身阻塞了.
3. main醒来后解锁,又睡1秒,为了等待goroutine运行. goroutine加锁成功,然后打印 “锁上了 (goroutine)”后就销毁了.
4. main醒来后,打印 “main exit.” 后退出.
- 多个goroutine抢占资源,使用互斥锁进行资源的唯一性访问.
测试程序:
package mainimport ( "fmt" "sync" "time")func main() { var mutex sync.Mutex fmt.Println("加锁. (main)") mutex.Lock() fmt.Println("锁上了 (main)") for i := 1; i <= 3; i++{ go func(i int) { fmt.Printf("加锁 (g%d)\n", i) mutex.Lock() // 对已经加锁的mutex进行重复加锁 fmt.Printf("锁上了 (g%d)\n", i) }(i) } time.Sleep(time.Second) // 等待所有goroutine都运行起来 fmt.Println("解锁了 (main)") mutex.Unlock() time.Sleep(time.Second) // 等待goroutine重新锁定互斥锁,只有一个能抢到互斥锁 fmt.Println("main exit")}
运行结果:
- 当对一个未加锁的互斥锁解锁时,会引发panic. 而且是无法recover() 的panic.
package mainimport ( "fmt" "sync")func main() { defer func() { fmt.Println("尝试恢复panic.") if p := recover(); p != nil { fmt.Println("已经恢复了 panic") } }() var mutex sync.Mutex fmt.Println("加锁") mutex.Lock() fmt.Println("锁上了") fmt.Println("解锁") mutex.Unlock() fmt.Println("解锁了") fmt.Println("再解锁") mutex.Unlock()}
结果:
总结
- 互斥锁(sync.Mutex)是为了确保对共享资源的唯一访问设计的.
- 重复加锁会阻塞进行重复加锁的线程.
- 解锁还没有加锁的互斥锁会引发无法避免的panic.
阅读全文
0 0
- Golang -- 互斥锁
- golang sync mutex 互斥锁
- Golang
- golang
- golang
- golang
- golang
- GOLANG
- golang
- golang
- golang
- golang
- golang
- golang
- Golang
- Golang
- Golang
- Golang
- Microsoft – WCF/OData – Deploying Services to IIS
- Android初学者的简单登录,利用外形资源和selector选择器
- 好玩的分词——python jieba分词模块的基本用法
- 特征选择-卡方检验用于特征选择
- 基于GUI的AWT,Swing写的一个餐厅点菜系统
- Golang -- 互斥锁
- 217. Contains Duplicate(疑问待解答)
- mysql之 [ERROR] InnoDB: Unable to lock ./ibdata1, error: 11
- 反反爬虫------设置scrapy随机user_agents
- 二叉树的简单应用--表达式树
- 接触Android
- 【有感】聆听哈佛幸福课 (上)
- AI高考的信息检索策略
- SpringSide实战(一)----SpringSide简介