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

【Golang 面试题】每日 3 题(三十一)

✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/UWz06
📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

91. Go 写锁怎么实现

加写锁

const rwmutexMaxReaders = 1 << 30
func (rw *RWMutex) Lock() {// First, resolve competition with other writers.rw.w.Lock()// Announce to readers there is a pending writer.r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders// Wait for active readers.if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {runtime_Semacquire(&rw.writerSem)}
}

首先调用互斥锁的 lock,获取到互斥锁之后,如果计算之后当前仍然有其他 goroutine 持有读锁,那么就调用 runtime_SemacquireMutex 休眠当前的 goroutine 等待所有的读操作完成

这里readerCount 原子性加上一个很大的负数,是防止后面的协程能拿到读锁,阻塞读

释放写锁

func (rw *RWMutex) Unlock() {// Announce to readers there is no active writer.r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders)// Unblock blocked readers, if any.for i := 0; i < int(r); i++ {runtime_Semrelease(&rw.readerSem, false)}// Allow other writers to proceed.rw.w.Unlock()
}

解锁的操作,会先调用 atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders) 将恢复之前写入的负数,然后根据当前有多少个读操作在等待,循环唤醒

92. Go 读写锁的注意事项以及区别

注意点:

  • 读锁或写锁在 Lock() 之前使用 Unlock() 会导致 panic 异常。
  • 使用 Lock() 加锁后,再次 Lock() 会导致死锁(不支持重入),需 Unlock() 解锁后才能再加锁。
  • 锁定状态与 goroutine 没有关联,一个 goroutine 可以 RLock(Lock),另一个 goroutine 可以 RUnlock(Unlock)。

互斥锁和读写锁的区别:

  • 读写锁区分读者和写者,而互斥锁不区分。
  • 互斥锁同一时间只允许一个线程访问该对象,无论读写;读写锁同一时间内只允许一个写者,但是允许多个读者同时读对象。

93. Go 互斥锁是什么?

Go sync 包提供了两种锁类型:互斥锁 sync.Mutex 和读写互斥锁 sync.RWMutex,都属于悲观锁。

概念:

Mutex是互斥锁,当一个 goroutine 获得了锁后,其他 goroutine 不能获取锁(只能存在一个写者或读者,不能同时读和写)

使用场景:

多个线程同时访问临界区,为保证数据的安全,锁住一些共享资源,以防止并发访问这些共享数据时可能导致的数据不一致问题。

获取锁的线程可以正常访问临界区,未获取到锁的线程等待锁释放后可以尝试获取锁

在这里插入图片描述

http://www.lryc.cn/news/521404.html

相关文章:

  • 微服务架构:挑战与机遇并存
  • Vue语音播报功能
  • 【Java设计模式-4】策略模式,消灭if/else迷宫的利器
  • citrix netscaler13.1 重写负载均衡响应头(基础版)
  • 【AI学习】地平线首席架构师苏箐关于自动驾驶的演讲
  • QILSTE H11-D212HRTCG/5M高亮红绿双色LED灯珠 发光二极管LED
  • 2️⃣java基础进阶——多线程、并发与线程池的基本使用
  • RAG多路召回
  • 复杂 C++ 项目堆栈保留以及 eBPF 性能分析
  • 网安——计算机网络基础
  • ZCC1923替代BOS1921Piezo Haptic Driver with Digital Front End
  • Kutools for Excel 简体中文版 - 官方正版授权
  • PostgreSQL和MySQL有什么区别?
  • 比较之舞,优雅演绎排序算法的智美篇章
  • C语言数据结构与算法(排序)详细版
  • JAVA:利用 RabbitMQ 死信队列实现支付超时场景的技术指南
  • pytest+request+yaml+allure搭建低编码调试门槛的接口自动化框架
  • Elasticsearch实战指南:从入门到高效使用
  • Open FPV VTX开源之嵌入式OSD配置
  • 2Hive表类型
  • 计算机网络之---公钥基础设施(PKI)
  • EF Core执行原生SQL语句
  • GaussDB分布式数据倾斜处理
  • 代码随想录Day34 | 62.不同路径,63.不同路径II,343.整数拆分,96.不同的二叉搜索树
  • vue.js辅助函数-mapMutations
  • Vue3组件设计模式:高可复用性组件开发实战
  • PHP 8.4 安装和升级指南
  • 什么是 OpenResty
  • Windows图形界面(GUI)-QT-C/C++ - QT控件创建管理初始化
  • 【计算机网络】lab8 DNS协议