Golang死锁vs操作系统死锁

目录

一、死锁

二、Golang死锁场景

[2.1 重复上锁](#2.1 重复上锁)

[2.2 不会减少的 WaitGroup](#2.2 不会减少的 WaitGroup)

[2.3 空select](#2.3 空select)

[2.4 channel](#2.4 channel)


一、死锁

1.golang中死锁的触发条件:

死锁是当 Goroutine 被阻塞而无法解除阻塞时产生的一种状态。

2.操作系统死锁:

发生死锁时,线程永远不能完成,系统资源被阻碍使用,以致于阻止了其他作业开始执行。在讨论处理死锁问题的各种方法之前,我们首先深入讨论一下死锁特点。

必要条件:

如果在一个系统中以下四个条件同时成立,那么就能引起死锁:

  • 互斥:至少有一个资源必须处于非共享模式,即一次只有一个线程可使用。如果另一线程申请该资源,那么申请线程应等到该资源释放为止。
  • 占有并等待:---个线程应占有至少一个资源,并等待另一个资源,而该资源为其他线程所占有。
  • 非抢占:资源不能被抢占,即资源只能被线程在完成任务后自愿释放。
  • 循环等待:有一组等待线程 {P0,P1,...,Pn},P0 等待的资源为 P1 占有,P1 等待的资源为 P2 占有,......,Pn-1 等待的资源为 Pn 占有,Pn 等待的资源为 P0 占有。

我们强调所有四个条件必须同时成立才会出现死锁。循环等待条件意味着占有并等待条件,这样四个条件并不完全独立。

二、Golang死锁场景

2.1 重复上锁

写写冲突,读写冲突,读读不冲突。golang中的锁是不可重入锁,对已经上了锁的写锁,再次申请锁是会报死锁。上了读锁的锁,再次申请写锁会报死锁,而申请读锁不会报错。

案例1:

重复上写锁

Go 复制代码
package main
import(
	"sync"
)
func main(){
	var lock sync.Mutex
	lock.Lock()
	lock.Lock()
}

结果:死锁

正常情况:

Go 复制代码
func main() {
	var lock sync.RWMutex
	lock.RLock()
	lock.RLock()
}
//正常执行

2.2 不会减少的 WaitGroup

不会减少的 WaitGroup会永久阻塞

案例1:

Go 复制代码
func main() {
	var wg sync.WaitGroup
	wg.Add(1)
	wg.Wait()
  //报死锁错误
}

结果:

2.3 空select

案例:

Go 复制代码
package main

func main() {
	select {
	
	}
}
//报死锁错误

结果:

2.4 channel

1.为 nil 的channel 发送、接受数据都会阻塞;

2.无缓冲的channel 发送、接受数据都会阻塞。解决方案:边接受边读取

3.channel 缓冲区满了的,继续发送数据会阻塞。解决办法:读取channel中的数据

4.当 ch 中没有数据的时候,就是从空的channel中接受数据,for range ch 会发生阻塞,但是无法解除阻塞,发生死锁。 解决:当数据发送完了过后,close channel

案例1:

Go 复制代码
func main() {
	var ch chan struct{}
	ch <- struct{}{}
}
//报死锁错误

结果:

案例2:

Go 复制代码
func main() {
	ch := make(chan struct{})
	<- ch
}
//报死锁错误

结果:

参考:关于golang中死锁的思考与学习_Golang_脚本之家

相关推荐
童先生5 小时前
Go 项目中实现类似 Java Shiro 的权限控制中间件?
开发语言·go
幼儿园老大*7 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
架构师那点事儿12 小时前
golang 用unsafe 无所畏惧,但使用不得到会panic
架构·go·掘金技术征文
于顾而言1 天前
【笔记】Go Coding In Go Way
后端·go
qq_172805591 天前
GIN 反向代理功能
后端·golang·go
follycat1 天前
2024强网杯Proxy
网络·学习·网络安全·go
OT.Ter2 天前
【力扣打卡系列】单调栈
算法·leetcode·职场和发展·go·单调栈
探索云原生2 天前
GPU 环境搭建指南:如何在裸机、Docker、K8s 等环境中使用 GPU
ai·云原生·kubernetes·go·gpu
OT.Ter2 天前
【力扣打卡系列】移动零(双指针)
算法·leetcode·职场和发展·go
码财小子2 天前
k8s 集群中 Golang pprof 工具的使用
后端·kubernetes·go