您的位置首页  散文杂谈

读写人(读写人官网)干货分享

互斥锁的根本就是当一个goroutine访问的时候,其他goroutine都不能访问,这样肯定保证了资源的同步,避免了竞争,不过也降低了性能。

读写人(读写人官网)干货分享

 

前面的有篇文章在讲资源竞争的时候,提到了互斥锁互斥锁的根本就是当一个goroutine访问的时候,其他goroutine都不能访问,这样肯定保证了资源的同步,避免了竞争,不过也降低了性能仔细剖析我们的场景,当我们读取一个数据的时候,如果这个数据永远不会被修改,那么其实是不存在资源竞争的问题的。

因为数据是不变的,不管怎么读取,多少goroutine同时读取,都是可以的所以其实读取并不是问题,问题主要是修改修改的数据要同步,这样其他goroutine才可以感知到所以真正的互斥应该是读取和修改、修改和修改之间,读取和读取是没有互斥操作的。

所以这就延伸出来另外一种锁,叫做读写锁读写锁可以让多个读操作同时并发,同时读取,但是对于写操作是完全互斥的也就是说,当一个goroutine进行写操作的时候,其他goroutine既不能进行读操作,也不能进行写操作。

package main import ( "sync""fmt""math/rand" ) var count intvar wg sync.WaitGroup var rw sync.RWMutex

funcmain() { wg.Add(10) for i:=0;i<5;i++ { go read(i) } for i:=0;i<5;i++ {

go write(i) } wg.Wait() } funcread(n int) { rw.RLock() fmt.Printf("读goroutine %d 正在读取...\n"

,n) v := count fmt.Printf("读goroutine %d 读取结束,值为:%d\n", n,v) wg.Done() rw.RUnlock() }

funcwrite(n int) { rw.Lock() fmt.Printf("写goroutine %d 正在写入...\n",n) v := rand.Intn(1000) count = v fmt.Printf(

"写goroutine %d 写入结束,新值为:%d\n", n,v) wg.Done() rw.Unlock() }我们在read里使用读锁,也就是RLock和RUnlock,写锁的方法名和我们平时使用的一样,是Lock和Unlock。

这样,我们就使用了读写锁,可以并发地读,但是同时只能有一个写,并且写的时候不能进行读操作现在我们再运行代码,可以从输出的数据看到,可以读到新值了我们同时也可以使用go build -race检测,也没有竞争提示了。

免责声明:本站所有信息均搜集自互联网,并不代表本站观点,本站不对其真实合法性负责。如有信息侵犯了您的权益,请告知,本站将立刻处理。联系QQ:1640731186