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

源码解读

相关推荐
earthzhang202134 分钟前
【1039】判断数正负
开发语言·数据结构·c++·算法·青少年编程
蕓晨37 分钟前
auto 自动类型推导以及注意事项
开发语言·c++·算法
mjhcsp1 小时前
C++ 递推与递归:两种算法思想的深度解析与实战
开发语言·c++·算法
m0_748248021 小时前
《详解 C++ Date 类的设计与实现:从运算符重载到功能测试》
java·开发语言·c++·算法
我命由我123452 小时前
Java 并发编程 - Delay(Delayed 概述、Delayed 实现、Delayed 使用、Delay 缓存实现、Delayed 延迟获取数据实现)
java·开发语言·后端·缓存·java-ee·intellij-idea·intellij idea
HLJ洛神千羽2 小时前
C++程序设计实验(黑龙江大学)
开发语言·c++·软件工程
kyle~2 小时前
算法数学---差分数组(Difference Array)
java·开发语言·算法
曹牧2 小时前
C#:三元运算符
开发语言·c#
Jonathan Star2 小时前
MediaPipe 在Python中实现人体运动识别,最常用且高效的方案是结合**姿态估计**(提取人体关键点)和**动作分类**(识别具体运动)
开发语言·python·分类
滨HI02 小时前
C++ opencv拟合直线
开发语言·c++·opencv