本文主要记录下go 语言中出现死锁的几种情况:

死锁定义

定义:整个代码所有的goroutine都阻塞了,当然也包括主goroutine

(1)重复锁定导致

就是说你对同一个锁进行了至少两次锁定(lock),不管你的锁是读写锁还是互斥锁,只要连续进行了至少两次锁定就会导致死锁,应发panic并且是运行时的panic,致命的bug,recover()都不能进行恢复。比如下面的代码:

package main

import (
	"sync"
	"fmt"
)

func main() {
	var lock sync.Mutex
	defer lock.Unlock()
	lock.Lock()// 第一次锁定
	lock.Lock()// 第二次锁定
	fmt.Println("test2 for testing deal lock")
}

lock.Lock()接连运行了两次,重复锁定了。
程序输出:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [semacquire]:
sync.runtime_SemacquireMutex(0xc00004c084, 0x428700)
	E:/Go/src/runtime/sema.go:71 +0x44
sync.(*Mutex).Lock(0xc00004c080)
	E:/Go/src/sync/mutex.go:134 +0x106

(2)解锁未锁定的锁

就是说代码中的某一把锁再尚未锁定的情况,你对他进行了解锁Unlock(),这也会导致死锁。同时这也是运行时panic,你无法恢复的。

package main

import (
	"sync"
	"fmt"
)

func main() {
	var lock sync.Mutex
	lock.Lock()
	lock.Unlock()// 第一次正常解锁,因为之前已经锁定了
	lock.Unlock()// 第二次进行解锁时,就会引发panic,因为处于未锁定状态
	fmt.Println("test2 for testing deal lock")
}