内容简介:函数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并发编程的艺术(十一)——倒计时器、同步屏障、信号量
- 多人游戏的网络实现:帧同步和状态同步
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。