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_脚本之家

相关推荐
csdn_aspnet17 小时前
Go语言常用算法深度解析:并发与性能的优雅实践
后端·golang·go
吴老弟i2 天前
Go 多版本管理实战指南
golang·go
Grassto2 天前
HTTP请求超时?大数据量下的网关超时问题处理方案,流式处理,附go语言实现
后端·http·golang·go
提笔了无痕3 天前
Web中Token验证如何实现(go语言)
前端·go·json·restful
Grassto3 天前
10 Go 是如何下载第三方包的?GOPROXY 与源码解析
后端·golang·go·go module
无心水4 天前
17、Go协程通关秘籍:主协程等待+多协程顺序执行实战解析
开发语言·前端·后端·算法·golang·go·2025博客之星评选投票
gjxDaniel4 天前
Go编程语言入门与常见问题
开发语言·后端·go
想用offer打牌4 天前
2025年总结:一个树苗倔强生长
java·后端·开源·go
StevenZeng学堂5 天前
一文读懂K8S的PV和PVC以及实践攻略
运维·docker·云原生·容器·kubernetes·云计算·go
你知道“铁甲小宝”吗丶5 天前
【第2章】第一个Go程序
后端·go