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

源码解读

相关推荐
沐知全栈开发2 小时前
React 表单与事件
开发语言
W.Buffer2 小时前
设计模式-单例模式:从原理到实战的三种经典实现
开发语言·javascript·单例模式
落羽的落羽2 小时前
【Linux系统】从零掌握make与Makefile:高效自动化构建项目的工具
linux·服务器·开发语言·c++·人工智能·机器学习·1024程序员节
-森屿安年-2 小时前
STL 容器:List
开发语言·c++·list·1024程序员节
uxiang_blog3 小时前
C++进阶:继承
开发语言·c++
赵杰伦cpp3 小时前
数据结构——二叉搜索树深度解析
开发语言·数据结构·c++·算法
扫地的小何尚3 小时前
一小时内使用NVIDIA Nemotron创建你自己的Bash计算机使用智能体
开发语言·人工智能·chrome·bash·gpu·nvidia
MoonBit月兔4 小时前
MoonBit Pearls Vol.12:初探 MoonBit 中的 JavaScript 交互
开发语言·javascript·数据库·交互·moonbit
草莓熊Lotso4 小时前
《算法闯关指南:优选算法--二分查找》--23.寻找旋转排序数组中的最小值,24.点名
开发语言·c++·算法·1024程序员节
foundbug9994 小时前
C# 实现 Modbus TCP 通信
开发语言·tcp/ip·c#