selectselectselectselect
死锁
在 Golang 中,死锁是一种非常令人头疼的问题。它指的是在程序中的一些 Goroutines 互相等待,导致所有 Goroutines 都无法向前推进。一个常见的死锁例子是两个 Goroutines 相互等待对方完成某个任务。
select
- 所有通道都被阻塞,并且没有默认操作。
- 所有通道都被阻塞,并且在有默认操作的情况下,未选择默认操作。
以下是一个死锁示例:
package main
import "time"
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
go func() {
for {
select {
case <-ch1:
ch2 <- 1
}
}
}()
// 这里的 select 语句会导致死锁,因为没有默认情况,且 ch1 和 ch2 都被阻塞
select {
case ch1 <- 1:
case <-ch2:
}
}
select
selectselect
defaultselect
以下是修改后的示例代码:
package main
import "time"
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
go func() {
for {
select {
case <-ch1:
ch2 <- 1
}
}
}()
// 这里的 select 语句中添加了一个默认情况,避免了死锁问题
select {
case ch1 <- 1:
case <-ch2:
default:
}
}
在上面的示例中,我们添加了一个默认情况。当所有的 case 都被阻塞时,该默认情况就会被执行,避免了死锁问题。
默认情况
select