go 使用 - sync.Metux

@[TOC](sync.metux 使用)

简介

复制代码
简述使用metux使用的方法, 使用的注意点, 以及使用情况

使用方法

提供的方法

Lock() 方法用于获取锁

Unlock() 方法用于释放锁

TryLock()方法尝试获取锁

对共享资源进行加锁, 例 :

go 复制代码
func increment() {
	// 加锁
	mutex.Lock()
	// 解锁
	defer mutex.Unlock()
	// 访问共享资源
	counter++
	fmt.Printf("Incremented: %d\n", counter)
	// 模拟一些工作
	time.Sleep(time.Millisecond * 100)
}

func main() {
	var wg sync.WaitGroup

	// 启动多个 goroutine 来模拟并发访问
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			increment()
		}()
	}
	// 等待所有 goroutine 完成
	wg.Wait()
	fmt.Println("Final Counter:", counter)
}
复制代码
Incremented: 1
Incremented: 2
Incremented: 3
Incremented: 4
Incremented: 5
Final Counter: 5

使用注意点

1、锁不可复制 , 例如需要用func 传递 metux 。 源码中锁结构中主要是一个state(记录锁的状态), 本来锁只有一把, 一个协程拿到一个锁, 如果复制了 那 俩把锁共享一个内存状态, 那就出错了。

go 复制代码
// 错误使用
func deal(m sync.Mutex) {
    ...
}

// 正确做法
func deal(m *sync.Mutex) {
    ...
}

2、 缩短、小锁使用的范围

go 复制代码
// 不建议 
mutex.Lock()
// 其他逻辑处理
counter++
// 其他逻辑处理
mutex.Unlock()

// 建议 
mutex.Lock()
	counter++
mutex.Unlock()

当然不能一概而论

go 复制代码
// 如果循环体内对共享资源的访问非常简单,而且锁的粒度很小,可能在循环内加锁更为合适。这样可以更细粒度地控制对共享资源的访问,减小锁的持有时间
for i := 0; i < 10; i++ {
    mutex.Lock()
    // 对共享资源的简单访问
    mutex.Unlock()
}
//  如果循环体内有复杂的逻辑,而且锁的粒度比较大,可能需要在循环外加锁,以避免在每次迭代时频繁地获取和释放锁,从而降低性能
mutex.Lock()
defer mutex.Unlock()
for i := 0; i < 10; i++ {
    // 复杂逻辑,可能涉及多个步骤
}

3、避免锁嵌套 可能会造成死锁的情况

例子是 《Concurrency in GO》-- 死锁一章

4、考虑使用读写锁, 在读多写少的情况下

5、如果想要锁用来通讯, 建议使用channel。 锁主要是保护共享资源的访问的。

使用场景

1、共享资源的访问

2、确保某个操作是原子的

这张图 也是 《Concurrency in GO》-并发哲学, 建议我们什么时候使用锁, 什么时候使用channel

源码解读

相关推荐
秋邱6 分钟前
Java匿名内部类的使用场景:从语法本质到实战优化全解析
android·java·开发语言·数据库·python
不会c嘎嘎7 分钟前
QT中的常用控件(一)
开发语言·qt
程序员阿鹏9 分钟前
RabbitMQ持久化到磁盘中有个节点断掉了怎么办?
java·开发语言·分布式·后端·spring·缓存·rabbitmq
资生算法程序员_畅想家_剑魔10 分钟前
Java常见技术分享-20-多线程安全-进阶模块-并发集合与线程池-ThreadPoolExecutor
java·开发语言
lsx20240617 分钟前
CSS 列表
开发语言
努力变大白17 分钟前
Python多指标综合评价及预测方法实战:CRITIC法+熵权法+TOPSIS+博弈论组合赋权综合评价预测全流程解析
开发语言·python
superman超哥24 分钟前
Rust 依赖管理与版本控制:Cargo 生态的精妙设计
开发语言·后端·rust·rust依赖管理·rust版本控制·cargo生态
资生算法程序员_畅想家_剑魔26 分钟前
Java常见技术分享-19-多线程安全-进阶模块-并发集合与线程池-线程池框架
java·开发语言
黎雁·泠崖26 分钟前
C 语言文件操作高阶:读取结束判定 + 缓冲区原理 + 常见错误
c语言·开发语言·缓存
沐知全栈开发29 分钟前
Ruby Dir 类和方法
开发语言