内容简介:函数write中的这条defer语句保证了在该函数被执行结束之前互斥锁mutex一定会被解锁。对于同一个读写锁来说,施加在它之上的读锁定可以有多个。因此,只有我们对互斥锁进行相同数量的读解锁,才能够让某一个相应的写锁定获得进行的机会。*sync.RWMutex类型都没有相应的方法让我们获得已进行的读锁定的数量,所以这里是很容易出现问题的。还好我们可以使用defer语句来尽量避免此类问题的发生。
锁
互斥锁
函数write中的这条defer语句保证了在该函数被执行结束之前互斥锁mutex一定会被解锁。
var mutex sync.Mutex
func write() {
mutex.Lock()
defer mutex.Unlock()
// 省略若干条语句
}
func repeatedlyLock() {
var mutex sync.Mutex
fmt.Println("Lock the lock. (G0)")
mutex.Lock()
fmt.Println("The lock is locked. (G0)")
for i := 1; i <= 3; i++ {
//开启3个协程,mutex已经锁定,所以程序会被阻塞。在unlock之后,随机启动一个。
go func(i int) {
//协程阻塞,只打印这一行。
fmt.Printf("Lock the lock. (G%d)\n", i)
mutex.Lock()
fmt.Printf("The lock is locked. (G%d)\n", i)
}(i)
}
time.Sleep(time.Second)
fmt.Println("Unlock the lock. (G0)")
mutex.Unlock()
fmt.Println("The lock is unlocked. (G0)")
time.Sleep(time.Second)
}
虽然互斥锁可以被直接的在多个Goroutine之间共享,但是我们还是强烈建议把对同一个互斥锁的成对的锁定和解锁操作放在同一个层次的代码块中。例如,在同一个函数或方法中对某个互斥锁的进行锁定和解锁。又例如,把互斥锁作为某一个结构体类型中的字段,以便在该类型的多个方法中使用它。
读写锁
- 多个写操作之间都是互斥的.
- 写操作与读操作之间也都是互斥的.
- 多个读操作之间却不存在互斥关系.
func (*RWMutex) Lock //写锁定 func (*RWMutex) Unlock //写解锁 func (*RWMutex) RLock //读锁定 func (*RWMutex) RUnlock //读解锁
对于同一个读写锁来说,施加在它之上的读锁定可以有多个。因此,只有我们对互斥锁进行相同数量的读解锁,才能够让某一个相应的写锁定获得进行的机会。*sync.RWMutex类型都没有相应的方法让我们获得已进行的读锁定的数量,所以这里是很容易出现问题的。还好我们可以使用defer语句来尽量避免此类问题的发生。
package main
import (
"sync"
"time"
)
var m *sync.RWMutex
func main() {
m = new(sync.RWMutex)
//可以多个同时读
go read(1)
go read(2)
time.Sleep(2 * time.Second)
}
func read(i int) {
println(i, "read start")
m.RLock()
println(i, "reading")
time.Sleep(1 * time.Second)
m.RUnlock()
println(i, "read end")
}
package main
import (
"sync"
"time"
)
var m *sync.RWMutex
func main() {
m = new(sync.RWMutex)
//写的时候啥都不能干
go write(1)
go read(2)
go write(3)
time.Sleep(4 * time.Second)
}
func read(i int) {
println(i, "read start")
m.RLock()
println(i, "reading")
time.Sleep(1 * time.Second)
m.RUnlock()
println(i, "read end")
}
//1 write end结束之后,2才能reading
//2 read end结束之后,3 才能writing
func write(i int) {
println(i, "write start")
m.Lock()
println(i, "writing")
time.Sleep(1 * time.Second)
m.Unlock()
println(i, "write end")
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Golang 并发编程与同步原语
- Java 并发编程:多线程并发访问,同步控制
- Java 并发编程:多线程并发访问,同步控制
- Visual Studio 发布新特性:实时同步编程、共同调试
- Java并发编程的艺术(十一)——倒计时器、同步屏障、信号量
- 多人游戏的网络实现:帧同步和状态同步
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Linux C编程一站式学习
宋劲杉 / 电子工业出版社 / 2009-12 / 60.00元
本书有两条线索,一条线索是以Linux平台为载体全面深入地介绍C语言的语法和程序的工作原理,另一条线索是介绍程序设计的基本思想和开发调试方法。本书分为两部分:第一部分讲解编程语言和程序设计的基本思想方法,让读者从概念上认识C语言;第二部分结合操作系统和体系结构的知识讲解程序的工作原理,让读者从本质上认识C语言。. 本书适合做零基础的初学者学习C语言的第一本教材,帮助读者打下牢固的基础。有一定......一起来看看 《Linux C编程一站式学习》 这本书的介绍吧!