- 1、本文档共10页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
GO语言并发编程之互斥锁、读写锁详解.doc
GO语言并发编程之互斥锁、读写锁详解
这篇文章主要介绍了GO语言并发编程之互斥锁、读写锁详解,本文是GO并发编程实战一书的样章,详细讲解了互斥锁、读写锁,然后给出了一个完整示例,需要的朋友可以参考下
在本节,我们对Go语言所提供的与锁有关的API进行说明。这包括了互斥锁和读写锁。我们在第6章描述过互斥锁,但却没有提到过读写锁。这两种锁对于传统的并发程序来说都是非常常用和重要的。
一、互斥锁
互斥锁是传统的并发程序对共享资源进行访问控制的主要手段。它由标准库代码包sync中的Mutex结构体类型代表。sync.Mutex类型(确切地说,是*sync.Mutex类型)只有两个公开方法——Lock和Unlock。顾名思义,前者被用于锁定当前的互斥量,而后者则被用来对当前的互斥量进行解锁。
类型sync.Mutex的零值表示了未被锁定的互斥量。也就是说,它是一个开箱即用的工具。我们只需对它进行简单声明就可以正常使用了,就像这样:
复制代码代码如下:
varmutexsync.Mutex
mutex.Lock()
在我们使用其他编程语言(比如C或Java)的锁类工具的时候,可能会犯的一个低级错误就是忘记及时解开已被锁住的锁,从而导致诸如流程执行异常、线程执行停滞甚至程序死锁等等一系列问题的发生。然而,在Go语言中,这个低级错误的发生几率极低。其主要原因是有defer语句的存在。
我们一般会在锁定互斥锁之后紧接着就用defer语句来保证该互斥锁的及时解锁。请看下面这个函数:
复制代码代码如下:
varmutexsync.Mutex
funcwrite(){
mutex.Lock()
defermutex.Unlock()
//省略若干条语句
}
函数write中的这条defer语句保证了在该函数被执行结束之前互斥锁mutex一定会被解锁。这省去了我们在所有return语句之前以及异常发生之时重复的附加解锁操作的工作。在函数的内部执行流程相对复杂的情况下,这个工作量是不容忽视的,并且极易出现遗漏和导致错误。所以,这里的defer语句总是必要的。在Go语言中,这是很重要的一个惯用法。我们应该养成这种良好的习惯。
对于同一个互斥锁的锁定操作和解锁操作总是应该成对的出现。如果我们锁定了一个已被锁定的互斥锁,那么进行重复锁定操作的Goroutine将会被阻塞,直到该互斥锁回到解锁状态。请看下面的示例:
复制代码代码如下:
funcrepeatedlyLock(){
varmutexsync.Mutex
fmt.Println(Lockthelock.(G0))
mutex.Lock()
fmt.Println(Thelockislocked.(G0))
fori:=1;i=3;i++{
gofunc(iint){
fmt.Printf(Lockthelock.(G%d)\n,i)
mutex.Lock()
fmt.Printf(Thelockislocked.(G%d)\n,i)
}(i)
}
time.Sleep(time.Second)
fmt.Println(Unlockthelock.(G0))
mutex.Unlock()
fmt.Println(Thelockisunlocked.(G0))
time.Sleep(time.Second)
}
我们把执行repeatedlyLock函数的Goroutine称为G0。而在repeatedlyLock函数中,我们又启用了3个Goroutine,并分别把它们命名为G1、G2和G3。可以看到,我们在启用这3个Goroutine之前就已经对互斥锁mutex进行了锁定,并且在这3个Goroutine将要执行的go函数的开始处也加入了对mutex的锁定操作。这样做的意义是模拟并发地对同一个互斥锁进行锁定的情形。当for语句被执行完毕之后,我们先让G0小睡1秒钟,以使运行时系统有充足的时间开始运行G1、G2和G3。在这之后,解锁mutex。为了能够让读者更加清晰地了解到repeatedlyLock函数被执行的情况,我们在这些锁定和解锁操作的前后加入了若干条打印语句,并在打印内容中添加了我们为这几个Goroutine起的名字。也由于这个原因,我们在repeatedlyLock函数的最后再次编写了一条“睡眠”语句,以此为可能出现的其他打印内容再等待一小会儿。
经过短暂的执行,标准输出上会出现如下内容:
复制代码代码如下:
Lockthelock.(G0)
Thelockislocked.(G0)
Lockthelock.(G1)
Lockthelock.(G2)
Lockthelock.(G3)
Unlockthelock.(G0)
Thelockisunlocked.(G0)
Thelockislocke
您可能关注的文档
- C语言编译器设计与实现毕业论文设计.doc.doc
- c语言销售管理系统.doc.doc
- DCT变换与KLT变换在图像压缩中的应用.doc.doc
- Dalvik虚拟机垃圾收集(GC)过程分析.doc.doc
- DJJ-8型接触网激光参数检测仪使用方法.doc.doc
- 第7章IS95数字蜂窝移动通信系统.ppt
- DLL的11种注入方法.doc.doc
- DRV8412地隔离和输出布局问题.doc.doc
- DZ经建科建设工程监理规范表格筛选模板.doc.doc
- dsp实验报告5.doc.doc
- 1.2.1 物质的量 课后练(含答案)高中化学 必修1(苏教版2019).doc
- 2.2.2 化学反应的计算 课后练(含答案)高中化学 必修1(苏教版2019).doc
- 【暑期衔接】专题07 补全对话与短文--2025年 译林版(三起)新四年级小学英语专项自学(含答解析).docx
- 【暑期衔接】专题06 补全对话与短文--2025年 人教精通版 新四年级(三升四) 小学英语专项自学(含解析).docx
- 2.3.2 原子核外电子排布 课后练(含答案)高中化学 必修1(苏教版2019).doc
- 【暑期衔接】专题06 任务型阅读--2025年 译林版(三起)新六年级(五升六)小学英语专项自学(含解析).docx
- 【暑期衔接】专题04 阅读理解--2025年 人教精通版 新四年级(三升四) 小学英语专项自学(含解析).docx
- 人工智能2.0时代的人才培养和通识教育课程建设202505711A.pptx
- 河北省定州中学2017-2018学年高二下学期第二次月考数学试题.doc
- 21.2.2公式法(课件)人教版九年级数学上册(1).pptx
文档评论(0)