0

0

如何使用互斥锁(Mutex)实现 Goroutine 的互斥执行

霞舞

霞舞

发布时间:2025-10-03 12:15:30

|

763人浏览过

|

来源于php中文网

原创

如何使用互斥锁(mutex)实现 goroutine 的互斥执行

本文介绍了如何使用 Go 语言的 sync 包中的 Mutex(互斥锁)来实现 Goroutine 的互斥执行。通过互斥锁,可以确保在同一时刻只有一个 Goroutine 可以访问共享资源,从而避免数据竞争和保证程序的正确性。本文将详细讲解 Mutex 的使用方法,并提供示例代码,帮助读者理解如何在并发场景下控制 Goroutine 的执行顺序。

并发编程中,控制对共享资源的访问至关重要。当多个 Goroutine 同时访问和修改同一份数据时,可能会出现数据竞争,导致程序行为异常甚至崩溃。Go 语言提供了多种同步机制来解决这个问题,其中 sync.Mutex(互斥锁)是一种常用的方式。

sync.Mutex 允许您锁定一段代码,使得在任何给定时间只有一个 Goroutine 可以执行该代码块。这对于保护共享资源免受并发访问的影响非常有用。

sync.Mutex 的基本用法

sync.Mutex 提供了两个主要方法:

  • Lock(): 尝试获取锁。如果锁当前被其他 Goroutine 持有,则调用 Goroutine 将阻塞,直到锁可用。
  • Unlock(): 释放锁。释放锁后,其他等待获取锁的 Goroutine 将有机会获得锁并继续执行。

以下是一个简单的示例,演示了如何使用 sync.Mutex 来保护对共享变量的访问:

SekoTalk
SekoTalk

商汤科技推出的AI对口型视频创作工具

下载
package main

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

var (
    counter int
    mutex   sync.Mutex
)

func incrementCounter(id int) {
    mutex.Lock() // 获取锁
    defer mutex.Unlock() // 确保函数退出时释放锁

    fmt.Printf("Goroutine %d: Counter before increment: %d\n", id, counter)
    counter++
    fmt.Printf("Goroutine %d: Counter after increment: %d\n", id, counter)
    time.Sleep(time.Millisecond * 100) // 模拟一些工作
}

func main() {
    var wg sync.WaitGroup

    for i := 1; i <= 3; i++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            incrementCounter(id)
        }(i)
    }

    wg.Wait() // 等待所有 Goroutine 完成
    fmt.Println("Final counter value:", counter)
}

在这个例子中:

  1. 我们声明了一个全局变量 counter 和一个 sync.Mutex 类型的变量 mutex。
  2. incrementCounter 函数负责递增 counter 的值。
  3. 在 incrementCounter 函数中,我们首先调用 mutex.Lock() 来获取锁。这将阻止其他 Goroutine 在当前 Goroutine 完成之前访问 counter。
  4. defer mutex.Unlock() 语句确保在函数退出时始终释放锁,即使函数发生 panic。
  5. 在 main 函数中,我们启动了三个 Goroutine,每个 Goroutine 都调用 incrementCounter 函数。
  6. wg.Wait() 确保主 Goroutine 等待所有子 Goroutine 完成。

运行此代码,您会看到每次只有一个 Goroutine 可以访问 counter,从而避免了数据竞争。

注意事项

  • 死锁: 如果 Goroutine 试图多次锁定同一个互斥锁而没有先释放它,就会发生死锁。例如:
mutex.Lock()
mutex.Lock() // 导致死锁
  • 避免长时间持有锁 长时间持有锁会降低程序的并发性。尽量减少持有锁的时间,只在必要时才锁定。
  • 使用 defer 释放锁: 始终使用 defer mutex.Unlock() 来确保在函数退出时释放锁,即使函数发生 panic。
  • 读写锁: 如果多个 Goroutine 需要读取共享资源,但只有一个 Goroutine 需要写入共享资源,则可以使用 sync.RWMutex(读写锁)来提高性能。读写锁允许多个 Goroutine 同时读取共享资源,但只允许一个 Goroutine 写入共享资源。

总结

sync.Mutex 是 Go 语言中用于实现互斥锁的一种简单而强大的机制。通过使用互斥锁,您可以确保在并发环境下对共享资源的访问是安全的,从而避免数据竞争和保证程序的正确性。理解 sync.Mutex 的基本用法和注意事项对于编写可靠的并发程序至关重要。

相关专题

更多
全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

73

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

96

2025.09.18

漫蛙2入口地址合集
漫蛙2入口地址合集

本专题整合了漫蛙2入口汇总,阅读专题下面的文章了解更多详细内容。

150

2026.01.06

AO3中文版地址汇总
AO3中文版地址汇总

本专题整合了AO3中文版地址合集,阅读专题下面的文章了解更多详细内容。

82

2026.01.06

python cv2模块教程大全
python cv2模块教程大全

本专题整合了python cv2模块相关教程,阅读专题下面的文章了解更多详细教程。

41

2026.01.06

python创建txt文件教程大全
python创建txt文件教程大全

本专题整合了python创建txt文件相关教程,阅读专题下面的文章了解更多详细内容。

21

2026.01.06

python去掉字符串空格教程大全
python去掉字符串空格教程大全

本专题整合了python去掉字符串空格教程大全,阅读专题下面的文章了解更多详细内容。

2

2026.01.06

Python /与// 教程大全
Python /与// 教程大全

本专题整合了python的/和//的相关内容大全,阅读下面的文章了解更多详细内容。

23

2026.01.06

Python /与// 教程大全
Python /与// 教程大全

本专题整合了python的/和//的相关内容大全,阅读下面的文章了解更多详细内容。

0

2026.01.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.4万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号