go语言学习笔记 — 进阶 — 并发编程:互斥锁(sync.Mutex)—— 保证同时只有一个goroutine可以访问共享资源

Posted Locutus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go语言学习笔记 — 进阶 — 并发编程:互斥锁(sync.Mutex)—— 保证同时只有一个goroutine可以访问共享资源相关的知识,希望对你有一定的参考价值。

互斥锁(英语:Mutual exclusion,缩写 Mutex)是一种在多线程编程中,防止两条线程同时对同一共享资源(比如全局变量)进行读写的机制。互斥锁通过把代码切片成一个个的临界区域(critical section)达成。临界区域指一块对公共资源进行访问的代码,并非一种机制或是算法。一个进程或线程可以拥有多个临界区域,但是并不一定会应用互斥锁。

需要此机制的资源有:队列、计数器、中断处理进程等用于在多条并行运行代码间传递数据、同步状态的资源。维护这些资源的同步、一致和完整是很困难的,因为一条线程可能在任何一个时刻被暂停(休眠)或者恢复(唤醒)。

package main

import (
	"fmt"
	"sync"
	"testing"
)

var (
	count      int        // 某个逻辑中使用的变量,如包级别变量、结构体成员字段变量
	countGuard sync.Mutex // 变量名+Guard,以表示这个互斥锁用于保护这个变量。一般情况下,把互斥锁的粒度设置得越小越好,降低共享访问的等待时间。
)

// 获取一个count值,通过这个函数可以并发安全地访问变量count
func GetCount() int {
	countGuard.Lock() // 对互斥量countGuard加锁。一旦互斥量被加锁,如果另一个goroutine尝试继续加锁时会发生阻塞,直到互斥量解锁

	defer countGuard.Unlock() // 在函数退出时解锁

	return count
}

// 设置一个count值,同样使用加锁解锁,保证修改count值的过程是一个原子过程,不会发生并发访问冲突
func SetCount(c int) {
	countGuard.Lock()
	count = c
	countGuard.Unlock()
}

func main() {
	for i := 0; i < 10; i++ {
		SetCount(i)             // 进行并发安全设置一个count值
		fmt.Println(GetCount()) // 进行并发安全获取
	}
}

以上是关于go语言学习笔记 — 进阶 — 并发编程:互斥锁(sync.Mutex)—— 保证同时只有一个goroutine可以访问共享资源的主要内容,如果未能解决你的问题,请参考以下文章

go语言学习笔记 — 进阶 — 并发编程:同步sync,竞态检测 —— 检测代码在并发环境下出现的问题

2.1 Go微服务实战(Go语言进阶) --- 并发编程进阶

go语言学习笔记 — 进阶 — 并发编程(11):同步sync,等待组(sync.WaitGroup)—— 保证在并发环境中完成指定数量的任务

Go语言自学系列 | golang并发编程之Mutex互斥锁实现同步

GO语言并发编程之互斥锁读写锁详解

Go并发编程之传统同步—互斥锁