Golang中互斥锁和读写互斥锁原理及示例代码

作者:周小末天天开心 时间:2024-05-29 22:06:52 

互斥锁

在Golang中,互斥锁(Mutex)是一种基本的同步原语,用于实现对共享资源的互斥访问。互斥锁通过在代码中标记临界区来控制对共享资源的访问,从而保证同一时间只有一个 goroutine 可以访问共享资源,避免了并发访问时的数据竞争和不一致性问题。

互斥锁的主要方法包括两个,分别是 Lock 和 Unlock。Lock 方法用于锁定共享资源,防止其他 goroutine 访问;Unlock 方法则用于解锁共享资源,允许其他 goroutine 访问。一般来说,在使用互斥锁时,需要先通过 Lock 方法锁定共享资源,访问共享资源,然后再通过 Unlock 方法解锁共享资源,让其他 goroutine 可以访问。

使用互斥锁的示例代码

package main
import (
   "fmt"
   "sync"
)
var count int
var mutex sync.Mutex
func increment() {
mutex.Lock()
count++
mutex.Unlock()
wg.Done()
}
func main() {
   for i := 0; i < 1000; i++ {
wg.Add(1)
go increment()
}
wg.Wait()
fmt.Println("Final count:", count)
}

在上面的示例代码中,increment函数是一个goroutine,它用来对count变量进行加1操作。在函数执行前通过mutex.Lock()获取互斥锁,在函数执行结束后通过mutex.Unlock()释放互斥锁。这样就保证了同一时刻只有一个goroutine可以访问count变量,从而避免了数据竞争的问题。

需要注意的是,在使用互斥锁时,一定要注意加锁和解锁的位置,否则可能会出现死锁的问题。

读写互斥锁

Go语言中的读写互斥锁(RWMutex)是一种特殊类型的互斥锁,它允许多个协程同时读取某个共享资源,但在写入时必须互斥,只能有一个协程进行写操作。相比互斥锁,读写互斥锁在高并发读的场景下可以提高并发性能,但在高并发写的场景下仍然存在性能瓶颈。

读写互斥锁有两个方法:RLock()和RUnlock()。在读取共享资源时,可以调用RLock()方法加读锁,在读取完成后,需要调用RUnlock()方法释放读锁。在写入共享资源时,需要调用Lock()方法加写锁,在写入完成后,需要调用Unlock()方法释放写锁。当有写锁或读写锁时,不能再加读锁或写锁,直到已经释放了所有锁。

读写互斥锁的示例代码

package main
import (
   "fmt"
   "sync"
   "time"
)
var (
   value    int
   rwLock   sync.RWMutex
   waitTime time.Duration = 100 * time.Millisecond
)
func readValue() {
   rwLock.RLock()
   defer rwLock.RUnlock()
   time.Sleep(waitTime)
   fmt.Println("Read value:", value)
}
func writeValue(val int) {
   rwLock.Lock()
   defer rwLock.Unlock()
   time.Sleep(waitTime)
   value = val
   fmt.Println("Write value:", value)
}
func main() {
   // 读操作可以并行执行
   for i := 0; i < 5; i++ {
       go readValue()
   }
   // 写操作必须等待读操作全部结束后才能执行
   for i := 0; i < 5; i++ {
       go writeValue(i)
   }
   // 等待所有goroutine执行完毕
   time.Sleep(time.Second)
}

在这个示例中,使用了一个全局变量value来存储值,使用了一个sync.RWMutex类型的变量rwLock来保护这个变量的读写。在readValue函数中,首先调用RLock方法获取读锁,然后等待一段时间,最后输出变量value的值。在writeValue函数中,首先调用Lock方法获取写锁,然后等待一段时间,将传入的值赋给变量value,最后输出变量value的值。

在main函数中,首先启动5个goroutine来执行readValue函数,这些goroutine可以并行执行。然后启动5个goroutine来执行writeValue函数,这些goroutine必须等待所有的读操作完成后才能执行,因为它们需要获取写锁。

需要注意的是,在使用读写互斥锁时,必须保证写操作只有一个,否则就会出现竞争状态,导致数据不一致的问题。同时也需要注意使用锁的力度,避免锁的范围过大,导致性能下降。

来源:https://blog.csdn.net/weixin_71646897/article/details/130658711

标签:Golang,互斥锁,读写互斥锁
0
投稿

猜你喜欢

  • Docker部署Python爬虫项目的方法步骤

    2023-03-27 14:45:21
  • Python入门(六)Python数据类型

    2022-08-19 21:09:11
  • MySQL 全文索引的原理与缺陷

    2024-01-16 18:54:16
  • Python3 replace()函数使用方法

    2023-07-21 22:25:13
  • python 的赋值语句和基本输入输出详解

    2021-07-29 13:55:55
  • 在Sql Server中调用外部EXE执行程序引发的问题

    2024-01-16 07:40:38
  • pymssql ntext字段调用问题解决方法

    2022-04-22 06:55:06
  • Python入门篇之字典

    2022-09-24 23:53:47
  • Pandas常用累计、同比、环比等统计方法实践过程

    2021-03-13 01:48:36
  • sqlserver 增删改查一些不常用的小技巧

    2024-01-24 06:49:59
  • 使用pyhon绘图比较两个手机屏幕大小(实例代码)

    2022-12-25 02:55:30
  • python归并排序算法过程实例讲解

    2023-12-02 23:28:06
  • python torch.utils.data.DataLoader使用方法

    2023-02-20 16:00:16
  • php 伪造本地文件包含漏洞的代码

    2023-11-17 06:36:40
  • python发送伪造的arp请求

    2022-11-24 00:47:35
  • Python实现的matplotlib动画演示之细胞自动机

    2022-05-23 15:49:09
  • python进程间数据交互的几种实现方式

    2022-11-05 09:32:12
  • python监测当前联网状态并连接的实例

    2023-04-19 03:33:19
  • 网页设计进阶之六-- 守住那些不能丢的东西

    2008-06-12 13:06:00
  • mysql一对多关联查询分页错误问题的解决方法

    2024-01-28 05:18:44
  • asp之家 网络编程 m.aspxhome.com