当前位置:首页 >> 综合

Go 互斥锁和读写互斥锁的完成

先来看多么一段代码,互斥互斥所存在的锁和锁问题 :

var wg sync.WaitGroupvar x int64func main() {  wg.Add(2) go f() go f() wg.Wait() fmt.Println(x) // 输进	:12135}func f()  {  for i:=0;i<10000;i++ {   x = x+1 } wg.Done() }

这里为甚么输进是 12135(不合的机械下场不一样),而不是读写20000 。

因为 x 的完成赋值 ,总共分为三个法度圭表类型  :掏出x的互斥互斥值、筹算x的锁和锁下场 、给x赋值。读写那么因为对f函数的完成调用采取了goroutine协程 ,所以存在成本竞争的互斥互斥问题 ,所以有赋值和筹算过程中存在脏数据。锁和锁对此类的读写问题,可以采取互斥锁措置:

互斥锁

互斥锁是完成一种经常独霸的独霸共享成本访谒的编制,它可以担保同时只需一个goroutine可以访谒共享成本。互斥互斥Go言语中独霸sync包的锁和锁Mutex圭表类型来完成互斥锁。

var wg sync.WaitGroupvar x int64var lock sync.Mutexfunc main() {  wg.Add(2) go f() go f() wg.Wait() fmt.Println(x) // 输进
:20000}func f()  {  for i:=0;i<10000;i++ {   lock.Lock() // 加互斥锁  x = x+1  lock.Unlock() // 解锁 } wg.Done() }

独霸互斥锁可以担保不应时分有且只需一个goroutine进进临界区 ,读写其他的goroutine则在等待锁;当互斥锁释放后,等待的goroutine才可以掉落踪掉落踪锁进进临界区 ,多个goroutine同时等待一个锁时 ,唤醒的计策是随机的 。

读写互斥锁

互斥锁是无缺互斥的,可是有良多理论的场景下是读多写少的,当我们并发的往读取一个成本不触及成本改削的时辰是没有需求加锁的,这类场景下独霸读写锁是更好的一种选择。读写锁在Go言语中独霸sync包中的RWMutex圭表类型。

读写锁分为两种 :读锁和写锁。当一个goroutine掉落踪掉落踪读锁此后 ,其他的goroutine假定是掉落踪掉落踪读锁会延续掉落踪掉落踪锁  ,假定是掉落踪掉落踪写锁就会等待;当一个goroutine掉落踪掉落踪写锁此后  ,其他的goroutine非论是掉落踪掉落踪读锁仍是写锁都邑等待 。

var ( x1 int64 wg1 sync.WaitGroup lock1 sync.Mutex rwlock sync.RWMutex)func main() {  startTime := time.Now() for i:=0;i<100;i++ {   wg1.Add(1)  write() } for i:=0;i<10000;i++ {   wg1.Add(1)  read() } wg1.Wait() fmt.Println(time.Now().Sub(startTime)) // 互斥锁用时
: 973.9304ms // 读写互斥锁用时: 718.094ms}func read()  {  defer wg1.Done() //lock1.Lock() // 互斥锁 rwlock.RLock() // 读写互斥锁 fmt.Println(x1) //lock1.Unlock() // 互斥锁 rwlock.RUnlock() // 读写互斥锁}func write()  {  defer wg1.Done() lock1.Lock() x1 = x1+1 lock1.Unlock()}

到此这篇关于Go 互斥锁和读写互斥锁的完成的文章就引见到这了,更多相干Go言语 互斥锁和读写互斥锁内容请搜刮完竣下载之前的文章或延续不雅不雅不雅不雅鉴赏上面的相干文章希看大年夜师往后多多支撑完竣下载!

  • 关注微信

猜你喜欢

微信公众号