0

0

Go 并发编程:互斥锁实现临界区访问控制

碧海醫心

碧海醫心

发布时间:2025-08-17 22:44:01

|

595人浏览过

|

来源于php中文网

原创

go 并发编程:互斥锁实现临界区访问控制

在 Go 语言的并发编程中,控制对共享资源的并发访问至关重要。虽然 Go 推荐使用 Go channels 进行 Goroutine 间的通信和同步,但在某些情况下,使用互斥锁(sync.Mutex)来保护临界区也是一种有效的手段。本文将介绍如何使用 sync.Mutex 来实现临界区访问控制,以避免数据竞争和其他并发问题。

使用 sync.Mutex 实现临界区

sync.Mutex 是 Go 标准库 sync 包提供的一种互斥锁。它提供了 Lock() 和 Unlock() 两个方法,用于控制对共享资源的访问。当一个 Goroutine 调用 Lock() 方法时,如果互斥锁未被占用,则该 Goroutine 获得锁,可以进入临界区;如果互斥锁已被其他 Goroutine 占用,则该 Goroutine 会阻塞,直到互斥锁被释放。当 Goroutine 完成对共享资源的访问后,需要调用 Unlock() 方法释放锁,以便其他 Goroutine 可以获得锁并访问共享资源。

以下是一个使用 sync.Mutex 的示例:

造次
造次

Liblib打造的AI原创IP视频创作社区

下载
package main

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

var (
    mutex   sync.Mutex
    counter int
    wg      sync.WaitGroup
)

func incrementCounter(id int) {
    defer wg.Done()

    for i := 0; i < 1000; i++ {
        // 在进入临界区之前执行一些操作
        fmt.Printf("Goroutine %d: Preparing to increment counter\n", id)
        time.Sleep(time.Millisecond * 1) // 模拟一些耗时操作

        // 获取锁,进入临界区
        mutex.Lock()
        fmt.Printf("Goroutine %d: Entering critical section\n", id)
        counter++ // 访问共享资源
        fmt.Printf("Goroutine %d: Counter value: %d\n", id, counter)
        // 释放锁,退出临界区
        mutex.Unlock()
        fmt.Printf("Goroutine %d: Exiting critical section\n", id)

        // 在退出临界区之后执行一些操作
        time.Sleep(time.Millisecond * 1) // 模拟一些耗时操作
        fmt.Printf("Goroutine %d: Finished incrementing counter\n", id)
    }
}

func main() {
    wg.Add(2)
    go incrementCounter(1)
    go incrementCounter(2)

    wg.Wait()
    fmt.Println("Final counter value:", counter)
}

在这个例子中,counter 是一个共享变量,incrementCounter 函数会并发地增加它的值。为了避免多个 Goroutine 同时修改 counter 导致数据竞争,我们使用 mutex.Lock() 和 mutex.Unlock() 来保护对 counter 的访问。只有获得锁的 Goroutine 才能进入临界区并修改 counter 的值。

注意事项

  • 避免死锁: 在使用互斥锁时,需要特别注意避免死锁的发生。死锁是指两个或多个 Goroutine 互相等待对方释放锁,导致程序无法继续执行的情况。为了避免死锁,可以遵循以下原则:
    • 避免嵌套锁:尽量避免在一个 Goroutine 中获取多个锁。
    • 使用超时:如果需要获取多个锁,可以设置超时时间,如果超时未获得锁,则释放已获得的锁,避免永久阻塞。
    • 保持锁的顺序一致:如果多个 Goroutine 需要获取相同的锁,应确保它们以相同的顺序获取锁。
  • 及时释放锁: 务必确保在完成对共享资源的访问后及时释放锁,否则其他 Goroutine 将无法访问共享资源,导致程序阻塞。可以使用 defer 语句来确保锁在函数退出时被释放,即使函数发生 panic 也会被执行。例如:
mutex.Lock()
defer mutex.Unlock()
// ... 临界区代码 ...
  • 优先使用 Go Channels: Go 语言的设计哲学是 "Don't communicate by sharing memory; share memory by communicating." 也就是说,尽可能使用 Go Channels 进行 Goroutine 间的通信和同步,而不是直接共享内存。Go Channels 提供了更安全、更简洁的并发编程模型。

总结

sync.Mutex 是 Go 语言中用于保护临界区的互斥锁。通过使用 Lock() 和 Unlock() 方法,可以确保在同一时刻只有一个 Goroutine 可以访问共享资源,从而避免数据竞争和其他并发问题。但是,在使用互斥锁时需要注意避免死锁,并及时释放锁。在可能的情况下,应优先使用 Go Channels 进行 Goroutine 间的通信和同步。

相关文章

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

2

2026.01.19

微信聊天记录删除恢复导出教程汇总
微信聊天记录删除恢复导出教程汇总

本专题整合了微信聊天记录相关教程大全,阅读专题下面的文章了解更多详细内容。

39

2026.01.18

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

99

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

148

2026.01.16

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

57

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

40

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

19

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

107

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

44

2026.01.15

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

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

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