Go语言的互斥锁Mutex
一、使用方法
Mutext是互斥锁的意思,也叫排他锁,同一时刻一段代码只能被一个线程运行,两个方法Lock(加锁)和Unlock(解锁)
func main() {
var count = 0
var wg sync.WaitGroup
//十个协程数量
n := 10
wg.Add(n)
for i := 0; i < n; i++ {
go func() {
defer wg.Done()
//1万叠加
for j := 0; j < 10000; j++ {
count++
}
}()
}
wg.Wait()
fmt.Println(count)
}
运行结果如下
38532
添加锁
func main() {
var count = 0
var wg sync.WaitGroup
var mu sync.Mutex
//十个协程数量
n := 10
wg.Add(n)
for i := 0; i < n; i++ {
go func() {
defer wg.Done()
//1万叠加
for j := 0; j < 10000; j++ {
mu.Lock()
count++
mu.Unlock()
}
}()
}
wg.Wait()
fmt.Println(count)
}
运行结果如下,可以看到,已经看到结果变成了正确的100000

二、死锁场景
当两个或两个以上的进程在执行过程中,因争夺资源而处理一种互相等待的状态,如果没有外部干涉无法继续下去,这时我们称系统处于死锁或产生了死锁
1.Lock/Unlock不是成对出现
良好的编程习惯应该是让mu.Lock()和 defer mu.Unlock()成对出现,能有效的降低死锁出现的概率,比如忘了Lock或忘了Unlock,代码建议以下面紧凑的方式出现
mu.Lock()
defer mu.Unlock()
2.锁被拷贝使用
package main
import (
"fmt"
"sync"
)
func main() {
var mu sync.Mutex
mu.Lock()
defer mu.Unlock()
copyTest(mu)
}
//这里复制了一个锁,造成了死锁
func copyTest(mu sync.Mutex) {
mu.Lock()
defer mu.Unlock()
fmt.Println("ok")
}
在函数外层已经加了一个Lock,在拷贝的时候又执行了一次Lock,因此这是一个永远不会获得的死锁
3.循环等待
A等待B,B等待C,C等待A,陷入了无限循环(哲学家就餐问题)
package main
import (
"sync"
)
func main() {
var muA, muB sync.Mutex
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
muA.Lock()
defer muA.Unlock()
//A依赖B
muB.Lock()
defer muB.Lock()
}()
go func() {
defer wg.Done()
muB.Lock()
defer muB.Lock()
//B依赖A
muA.Lock()
defer muA.Unlock()
}()
wg.Wait()
}
Go语言的互斥锁Mutex的更多相关文章
- 互斥锁Mutex与信号量Semaphore的区别
转自互斥锁Mutex与信号量Semaphore的区别 多线程编程中,常常会遇到这两个概念:Mutex和Semaphore,两者之间区别如下: 有人做过如下类比: Mutex是一把钥匙,一个人拿了就可进 ...
- 深入理解Solaris内核中互斥锁(mutex)与条件变量(condvar)之协同工作原理
在Solaris上写内核模块总是会用到互斥锁(mutex)与条件变量(condvar), 光阴荏苒日月如梭弹指一挥间,Solaris的大船说沉就要沉了,此刻心情不是太好(Orz).每次被年轻的有才华的 ...
- Linux内核互斥锁--mutex
一.定义: /linux/include/linux/mutex.h 二.作用及访问规则: 互斥锁主要用于实现内核中的互斥访问功能.内核互斥锁是在原子 API 之上实现的,但这对于内核用户是不可见 ...
- 线程锁(互斥锁Mutex)及递归锁
一.线程锁(互斥锁) 在一个程序内,主进程可以启动很多个线程,这些线程都可以访问主进程的内存空间,在Python中虽然有了GIL,同一时间只有一个线程在运行,可是这些线程的调度都归系统,操作系统有自身 ...
- 线程锁(互斥锁Mutex)
线程锁(互斥锁Mutex) 一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据,此时,如果2个线程同时要修改同一份数据,会出现什么状况? # -*- cod ...
- Golang 读写锁RWMutex 互斥锁Mutex 源码详解
前言 Golang中有两种类型的锁,Mutex (互斥锁)和RWMutex(读写锁)对于这两种锁的使用这里就不多说了,本文主要侧重于从源码的角度分析这两种锁的具体实现. 引子问题 我一般喜欢带着问题去 ...
- 一文带你剖析LiteOS互斥锁Mutex源代码
摘要:多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的临界资源,只能被独占使用.LiteOS使用互斥锁来避免这种冲突,互斥锁是一种特殊的二值性信号量,用于实现对临界资源的独占 ...
- [Go] golang互斥锁mutex
1.互斥锁用于在代码上创建一个临界区,保证同一时间只有一个goroutine可以执行这个临界区代码2.Lock()和Unlock()定义临界区 package main import ( " ...
- Go基础系列:互斥锁Mutex和读写锁RWMutex用法详述
sync.Mutex Go中使用sync.Mutex类型实现mutex(排他锁.互斥锁).在源代码的sync/mutex.go文件中,有如下定义: // A Mutex is a mutual exc ...
随机推荐
- Apache CXF基本使用
一.服务端开发 1.创建web项目 2.导入jar包 3.web.xml中配置Servlet 1 <!-- 配置CXF框架提供的Servlet --> 2 <servlet> ...
- linux_命令格式和命令提示符
# linux 中一切皆文件 命令格式: 命令 [功能选项] [文件路径] cmd [options] [path] # 多个功能选项,要放在一起,如 rsync -avz /backup backu ...
- 手把手教你ASP.NET Core:使用Entity Framework Core进行增删改查
新建表Todo,如图 添加模型类 在"解决方案资源管理器"中,右键单击项目. 选择"添加" > "新建文件夹". 将文件夹命名为 Mo ...
- 中秋国庆8天挑战赛 之 挑战8天掌握微信小程序
中秋国庆8天挑战赛 挑战8天掌握微信小程序 当前学习进度: // 10.1// 学习内容:// 10.2// 学习内容:// 10.3// 学习内容:// 10.4// 学习内容:// ...
- PHP代码审计02之filter_var()函数缺陷
前言 根据红日安全写的文章,学习PHP代码审计审计的第二节内容,题目均来自PHP SECURITY CALENDAR 2017,讲完这个题目,会有一道CTF题目来进行巩固,外加一个实例来深入分析,想了 ...
- 别人写的很好Arduino教材
原文来自:https://www.arduino.cn/thread-31720-1-1.html 上一篇:Arduino教程--通过 库管理器 添加库 http://www.arduino.cn/t ...
- Linux 安装Navicat Premium 15
参考:https://gitee.com/andisolo/navicat-keygen 安装 aptitude 管理软件 $ sudo apt-get install aptitude 安装Navi ...
- c#类(class)
类 类的定义是以关键字class开始的,后面跟类的名称,类的主题包含一个花括号里,下面是类定义的一般格式. <access specifier> class class_name { // ...
- JVM初步入门(很初级,建议只做大致了解用)
jvm初步入门 本博客中的所有内容都是来自b站狂神说视频教程,如有侵权联系我删除. 下面是视频链接:b站狂神说 关于jvm的几个小问题 1. jvm的位置: jvm是一个运行在操作系统上的用c语言编写 ...
- Android和。net加密。
来源: Github: https://github.com/Pavel-Durov/CodeProject-Android-and-NET-Encryption 直接: Source Code (A ...