当前位置:网站首页>Several interview questions about golang concurrency
Several interview questions about golang concurrency
2022-08-01 23:37:00 【youngqqcn】
May I ask what happens if you run the following program? ( )
- A: 不能编译
- B: 输出 main --> A --> B --> C
- C: 输出 main
- D: panic
package main
import (
"fmt"
"sync"
)
var mu sync.Mutex
var chain string
func main() {
chain = "main"
A()
fmt.Println(chain)
}
func A() {
mu.Lock()
defer mu.Unlock()
chain = chain + " --> A"
B()
}
func B() {
chain = chain + " --> B"
C()
}
func C() {
mu.Lock()
defer mu.Unlock()
chain = chain + " --> C"
}
,
,
,
,
,
,
,
答案:panic
死锁
为什么?
// 引自: https://www.jianshu.com/p/679041bdaa39
Mutex(互斥锁)
- Mutex 为互斥锁,Lock() 加锁,Unlock() 解锁
- 在一个 goroutine 获得 Mutex 后,其他 goroutine 只能等到这个 goroutine 释放该 Mutex
- 使用 Lock() 加锁后,不能再继续对其加锁,直到利用 Unlock() 解锁后才能再加锁
- 在 Lock() 之前使用 Unlock() 会导致 panic 异常
- 已经锁定的 Mutex 并不与特定的 goroutine 相关联,这样可以利用一个 goroutine 对其加锁,再利用其他 goroutine 对其解锁
- 在同一个 goroutine 中的 Mutex 解锁之前再次进行加锁,会导致死锁
- 适用于读写不确定,并且只有一个读或者写的场景
May I ask what happens if you run the following program? ( )
- A: 不能编译
- B: 输出 1
- C: 程序hang住
- D: panic
package main
import (
"fmt"
"sync"
"time"
)
var mu sync.RWMutex
var count int
func main() {
go A()
time.Sleep(2 * time.Second)
mu.Lock()
defer mu.Unlock()
count++
fmt.Println(count)
}
func A() {
mu.RLock()
defer mu.RUnlock()
B()
}
func B() {
time.Sleep(5 * time.Second)
C()
}
func C() {
mu.RLock()
defer mu.RUnlock()
}
,
,
,
,
,
,
,
,
,
,
,
,
答案:panic
死锁
为什么?
// 引自: https://www.jianshu.com/p/679041bdaa39
RWMutex(读写锁)
- RWMutex 是单写多读锁,该锁可以加多个读锁或者一个写锁
- 读锁占用的情况下会阻止写,不会阻止读,多个 goroutine 可以同时获取读锁
- 写锁会阻止其他 goroutine(无论读和写)进来,整个锁由该 goroutine 独占
- 适用于读多写少的场景
Lock() 和 Unlock()
- Lock() 加写锁,Unlock() 解写锁
- 如果在加写锁之前已经有其他的读锁和写锁,则 Lock() 会阻塞直到该锁可用,为确保该锁可用,已经阻塞的 Lock() 调用会从获得的锁中排除新的读取器,即写锁权限高于读锁,有写锁时优先进行写锁定
- 在 Lock() 之前使用 Unlock() 会导致 panic 异常
RLock() 和 RUnlock()
- RLock() 加读锁,RUnlock() 解读锁
- RLock() 加读锁时,如果存在写锁,A read lock cannot be added;当只有读锁或者没有锁时,可以加读锁,读锁可以加载多个
- RUnlock() 解读锁,RUnlock() undo word RLock() 调用,对于其他同时存在的读锁则没有效果
- 在没有读锁的情况下调用 RUnlock() 会导致 panic 错误
- RUnlock() 的个数不得多余 RLock(),否则会导致 panic 错误
Will the following program run? ( )
- A: 不能编译
- B: 无输出,正常退出
- C: 程序hang住
- D: panic
package main
import (
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
time.Sleep(time.Millisecond)
wg.Done()
wg.Add(1)
}()
wg.Wait()
}
,
,
,
,
,
,
,
,
,
答案:panic
, 会出现panic: sync: WaitGroup is reused before previous Wait has returned
panic: sync: WaitGroup is reused before previous Wait has returned
goroutine 1 [running]:
sync.(*WaitGroup).Wait(0x45f280?)
/usr/local/go/src/sync/waitgroup.go:138 +0x85
main.main()
/home/yqq/mine/master-go/interview/6-interview-golang/solution31.go:14 +0x85
边栏推荐
猜你喜欢
Access the selected node in the console
Background project Express-Mysql-Vue3-TS-Pinia page layout-sidebar menu
PDF转Word有那么难吗?做一个文件转换器,都解决了
软技能之UML图
简单3D渲染器的制作
C#大型互联网平台管理框架源码:基于ASP.NET MVC+EF6+Bootstrap开发,支持多数据库
中职网络安全竞赛B7比赛部署流程
Making a Simple 3D Renderer
深度学习基础-基于Numpy的循环神经网络(RNN)实现和反向传播训练
Leetcode 129求根节点到叶节点数字之和、104二叉树的最大深度、8字符串转换整数(atoi)、82删除排序链表中的重复元素II、204二分查找、94二叉树的中序遍历、144二叉树的前序遍历
随机推荐
Additional Features for Scripting
Department project source code sharing
毕业作业
中职网络安全竞赛B7比赛部署流程
6133. 分组的最大数量
Dynamic Scene Deblurring with Parameter Selective Sharing and Nested Skip Connections
Spark Sql之join on and和where
D - Linear Probing- 并查集
请问什么是 CICD
怎样做才能让这条SQL变成一条危险的SQL?
Calculate the midpoint between two points
LocalDateTime转为Date类型
【C语言进阶】文件操作(二)
程序员如何优雅地解决线上问题?
在CDH的hue上的oozie出现,提交 Coordinator My Schedule 时出错
Flink学习第五天——Flink可视化控制台依赖配置和界面介绍
获取小猪民宿(短租)数据
chrome copies the base64 data of an image
FAST-LIO2代码解析(二)
Calculate the distance between two points