NEWS DETAIL

golang面经5:sync相关

发布时间:2026/10/12 1:40:20 · 栏目:资讯中心

尧图网络原创建站知识分享正文
1.除了 mutex 以外还有那些方式可以安全读写共享变量?分析:除了Mutex,主要还有信号量、通道(Channel),原子操作(atomic)这几种方式。信号量的实现其实跟mutex差不多,实现起来也很方便,主要通过信号量计数来保证。chanenl是Go最推崇的方式,它通过通信来传递数据所有权,从根源上避免竞争,更适合复杂的业务逻辑;而原子操作则针对最简单的整型或指针等进行无锁操作,性能最高,常用于实现计数器或状态位。选择哪种,完全取决于数据结构的复杂度和业务的读写模型。信号量的使用示例如下:package main import ( "context" "fmt" "golang.org/x/sync/semaphore" "time" ) func main() { // 创建一个最多允许 3 个并发的信号量 sem := semaphore.NewWeighted(3) // 启动 10 个任务 for i := 0; i 10; i++ { go func(id int) { // 请求获取一个执行“名额” sem.Acquire(context.Background(), 1) // 模拟任务执行 fmt.Printf("Task %d is running\n", id) time.Sleep(2 * time.Second) fmt.Printf("Task %d is done\n", id) // 释放“名额” sem.Release(1) }(i) } // 等待所有任务完成 time.Sleep(25 * time.Second) } /* Task 0 is running Task 1 is running Task 2 is running ... (2秒后) Task 0 is done Task 3 is running ... */使用channel实现互斥package main import ( "fmt" "sync" "time" ) type ChannelMutex struct { ch chan struct{} } func NewChannelMutex() *ChannelMutex { mu := ChannelMutex{ ch: make(chan struct{}, 1), } mu.ch - struct{}{} // 放入初始令牌 return mu } func (m *ChannelMutex) Lock() { -m.ch } func (m *ChannelMutex) Unlock() { select { case m.ch - struct{}{}: default: panic("unlock of unlocked mutex") } } func main() { mutex := NewChannelMutex() var sharedData int var wg sync.WaitGroup // 创建多个并发的goroutine for i := 0; i 10; i++ { wg.Add(1) go func(id int) { defer wg.Done() // 获取锁 mutex.Lock() fmt.Printf("Goroutine %d acquired lock\n", id) // 访问临界区 temp := sharedData time.Sleep(50 * time.Millisecond) // 模拟工作 sharedData = temp + 1 fmt.Printf("Goroutine %d: sharedData = %d\n", id, sharedData) // 释放锁 mutex.Unlock() fmt.Printf("Goroutine %d released lock\n", id) }(i) } wg.Wait() fmt.Printf("Final value: %d\n", sharedData) }2.Go 如何实现原子操作?Go语言实现原子操作,其根本是依赖底层CPU硬件提供的原子指令,而不是通过操作系统或更上层的锁机制。具体来说, Go的 sync/atomic 包中的函数, 在编译时会被编译器识别, 并直接转换成对应目标硬件平台(如x86、 ARM) 的单条原子机器指令。 例如, 在x86架构上, atomic.AddInt64 这类操作会对应到像LOCK; ADD 这样的指令。 前面的 LOCK 前缀是关键, 它会锁住总线或缓存行, 确保后续的 ADD 指令在执行期间,其他CPU核心不能访问这块内存,从而保证了整个操作的原子性。 通常用来计数、状态记录等简单操作。回答:原子操作是一组不可中断的指令序列,由底层硬件支持,go语言的原子操作由sync/atomic包提供。1.19之后可以使用原子类型// 1.19之前 package main import ( "fmt" "sync" "sync/atomic" ) func main() { var counter int64 // 必须是 int64 类型 var wg sync.WaitGroup for i := 0; i 1000; i++ { wg.Add(1) go func() { defer wg.Done() atomic.AddInt64(counter, 1) // 原子增加 }() } wg.Wait() fmt.Println("Counter:", counter) // 输出一定是 1000 } // 1.19之后 var counter atomic.Int64 var wg sync.WaitGroup for i := 0; i 1000; i++ { wg.Add(1) go func() { defer wg.Done() counter.Add(1) // 直接使用 .Add(),无需传指针 }() } wg.Wait() fmt.Println("Counter:", counter.Load()) // 输出 1000add是“+”的操作,返回
✦

本文为尧图网络原创建站知识分享。想针对自身行业获取定制化建站方案?欢迎咨询,资深顾问免费为你出思路。

RELATED

相关 资讯推荐

MORE

更多 新鲜资讯

JMeter入门实战:从零构建HTTP接口性能测试脚本与结果分析
2026/10/10 15:43:34

JMeter入门实战:从零构建HTTP接口性能测试脚本与结果分析

1. 项目概述:从零开始,用JMeter搞定HTTP性能测试 刚接触性能测试的新手,或者是从功能测试转过来的朋友,一听到“压测”两个字,心里可能就有点发怵。工具那么多,概念那么杂,从哪儿下手呢&#xf…

Earendel: 一个纯TS写的POSIX兼容的微内核Web操作系统
2026/10/10 15:43:34

Earendel: 一个纯TS写的POSIX兼容的微内核Web操作系统

最近我用TypeScript写了一个运行在浏览器里的Web操作系统 Earendel(目前已知的距离地球最遥远的恒星)。开发它的初衷主要是为了Linux和操作系统课程的教学。市面上绝大多数Web OS项目,要么只是做了一个长得像Windows/macOS的网页UI拼盘&#…

5分钟掌握Windows防撤回神器:让微信QQ撤回消息无处遁形[特殊字符]
2026/10/12 8:28:31

5分钟掌握Windows防撤回神器:让微信QQ撤回消息无处遁形[特殊字符]

5分钟掌握Windows防撤回神器:让微信QQ撤回消息无处遁形🚀 【免费下载链接】RevokeMsgPatcher :trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁(我已经看到了,撤回也没用了) 项目地址: http…

从零制作同人动画:技术路线、流程与实战避坑指南
2026/10/11 15:38:19

从零制作同人动画:技术路线、流程与实战避坑指南

1. 先搞清楚这个“粉丝动画”到底是什么,以及它能解决什么问题看到“五条悟VS宿傩/咒术回战粉丝动画”这个标题,很多人的第一反应可能是去找一个现成的视频。但如果你是一个想自己动手创作、或者想了解这类作品背后技术流程的创作者,这个标题…

闭源降价80%,开源却在涨价:AI定价的交叉路口
2026/10/11 15:39:17

闭源降价80%,开源却在涨价:AI定价的交叉路口

8月6日,两条价格曲线悄然交汇。 一条向下:OpenAI把GPT-5.6 Luna的输出价格从6美元砍到1.2美元/百万Token,降幅80%。另一条向上:同一天,DeepSeek公告全线涨价,措辞是"涨幅较大",非试探…

产线三防平板选哪个牌子?5个品牌实测告诉你别瞎买
2026/10/12 11:16:12

产线三防平板选哪个牌子?5个品牌实测告诉你别瞎买

产线三防平板选哪个牌子?5个品牌实测告诉你别瞎买经常有工厂朋友拿着网上的"三防平板十大品牌排行榜"来问我:到底选哪个?说实话排行榜看看就行,真正选型得看你产线什么场景。今天挑五个在产线数字化里用得比较多的品牌—…

看完这篇,还想了解更多?

预约尧图网络顾问一对一沟通,针对你的行业与现状给出建站建议,全程免费。

免费咨询