当前位置: 首页 > article >正文

Go语言并发控制:sync.Mutex、sync.RWMutex和sync.WaitGroup详解

在Go语言中,编写并发程序是家常便饭。Go提供了多种并发原语来帮助我们管理并发,其中sync.Mutexsync.RWMutexsync.WaitGroup是三个非常常用的同步原语。本文将详细介绍这三个同步原语,并提供示例代码帮助理解它们的使用。

sync.Mutex

sync.Mutex是一个互斥锁,用于保护临界区,确保同一时间只有一个goroutine可以访问共享资源。互斥锁有两种状态:锁定和解锁。当一个goroutine获取(锁定)互斥锁时,其他尝试获取该锁的goroutines将被阻塞,直到锁被释放(解锁)。

示例代码

package main

import (
	"fmt"
	"sync"
)

func main() {
	var mutex sync.Mutex
	var wg sync.WaitGroup

	wg.Add(2)
	go func() {
		defer wg.Done()
		mutex.Lock()
		fmt.Println("goroutine 1 is accessing shared resource")
		mutex.Unlock()
	}()

	go func() {
		defer wg.Done()
		mutex.Lock()
		fmt.Println("goroutine 2 is accessing shared resource")
		mutex.Unlock()
	}()

	wg.Wait()
}

在这个例子中,两个goroutines尝试访问共享资源,但是由于互斥锁的存在,它们不会同时访问。

sync.RWMutex

sync.RWMutex是一个读写互斥锁,它允许多个goroutines同时读取共享资源,但是在写入时会锁定互斥锁,确保没有其他goroutine正在读取或写入。这在读取操作远多于写入操作的场景中非常有用,因为它可以提高并发性能。

示例代码

package main

import (
	"fmt"
	"sync"
)

var (
	sum  int
	mutex sync.RWMutex
)

func main() {
	var wg sync.WaitGroup
	wg.Add(110)

	for i := 1; i <= 100; i++ {
		go func() {
			defer wg.Done()
			add(10)
		}()
	}

	for i := 1; i <= 10; i++ {
		go func() {
			defer wg.Done()
			fmt.Println("sum的值:", readSum())
		}()
	}

	wg.Wait()
	fmt.Println("sum:", sum)
}

func add(num int) {
	mutex.Lock()
	defer mutex.Unlock()
	sum += num
}

func readSum() int {
	mutex.RLock()
	defer mutex.RUnlock()
	b := sum
	return b
}

在这个例子中,add函数修改共享资源sum,而readSum函数读取sum。由于readSum被频繁调用,使用sync.RWMutex可以提高程序的并发性能。

sync.WaitGroup

sync.WaitGroup用于等待一组goroutines完成。它计数goroutines的数量,并在所有goroutines完成它们的工作后通知主goroutine。

示例代码

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var wg sync.WaitGroup

	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			time.Sleep(time.Second)
			fmt.Printf("goroutine %d finished\n", i)
		}(i)
	}

	wg.Wait()
	fmt.Println("所有goroutines已完成")
}

在这个例子中,我们启动了5个goroutines,每个goroutine在完成它的工作后调用wg.Done()来减少WaitGroup的计数。主goroutine调用wg.Wait()来等待所有goroutines完成。

总结

sync.Mutexsync.RWMutexsync.WaitGroup是Go语言中非常重要的同步原语,它们帮助我们安全地管理并发,避免竞态条件和死锁。通过合理使用这些同步原语,我们可以编写出高效且安全的并发程序。


http://www.kler.cn/a/404161.html

相关文章:

  • ML 系列:第 26 节 - 连续概率分布(均匀分布)
  • 【数据结构】【线性表】栈的基本概念(附c语言源码)
  • Android Studio不显示需要的tag日志解决办法《All logs entries are hidden by the filter》
  • Stable diffusion详细讲解
  • JDBC 调用带输入和输出参数的存储过程
  • 【 模型】 开源图像模型Stable Diffusion入门手册
  • 实时数仓:Lambda架构和Kappa架构有什么联系和区别
  • 点餐管理系统设计与实现(Java+SpringBoot+MySql)
  • quick 2 — qml 与c++的混合编程
  • 熟悉的 Docker,陌生的 Podman
  • undefined 和 null 区别?
  • Linux 系统下的硬件视频加速
  • MyBatis实践:提高持久化层数据处理效率
  • 1、HCIP之RSTP协议与STP相关安全配置
  • Android App获取自己的公网IP地址
  • Elasticsearch面试内容整理-实践与应用场景
  • ComfyUI绘画|Stable Diffusion原理的简易讲解
  • 2024年亚太地区数学建模C题完整思路
  • “闲置经济”成新消费趋势,万物新生长期成长性如何?
  • 早期超大规模语言模型的尝试——BLOOM模型论文解读,附使用MindSpore和MindNLP的模型和实验复现