目录
- 死锁1:一个通道在一个主go程里同时进行读和写
- 死锁2:go程开启之前使用通道
- 死锁3 :通道1中调用了通道2,通道2中调用通道1
- 死锁4:读取空channel 死锁
- 死锁5:超过channel缓存继续写入数据导致死锁
- 死锁6:向已关闭的chan编程客栈nel中写入数据不会导致死锁,但是回出发panic异常
死锁是指两个或两个以上的协程fMbgym的执行过程中,由于竞争资源或由于彼此通信而造成的一种阻塞的现象,若无外力作用,他们将无法推进下去,以下是总结出来的几种死锁情况。
1.死锁1:一个通道在一个主go程里同时进行读和写
2.死锁2:go程开启之前使用通道3.死锁3 :通道1中调用了通道2,通道2中调用通道14.死锁4:直接读取空channel的死锁5.死锁5:超过channel缓存继续写入数据导致死锁6.向已关闭的channel中写入数据不会导致死锁,但是回出发panic异常死锁1:一个通道在一个主go程里同时进行读和写
func main() { // 死锁1 ch := make(chan int) ch <- 100 num := <-ch fmt.Println("num=", num) }
还有另外一个场景:下面的场景是因为语句中的 <-ch1 是在主协程中先求值,会导致主协程阻塞。
package main import ( "fmt" "time" ) func main() { ch1 := make(chan int) go fmt.Println(<-ch1) ch1 <- 5 time.Sleep(1 * time.Second) }
死锁2:go程开启之前使用通道
func main() { ch := make(chan int) ch <- 100 //此处死锁 优于go程之前使用通道 go func() { num := python<-ch fmt.Println("num=", num) }() //ch <- 100 此处不死锁 time.Sleep(time.Second*3) fmt.Println("finish") }
死锁3 :通道1中调用了通道2,通道2中调用通道1
// 死锁3 func main() { ch1 := make(chan int ) ch2 := make(chan int ) go func() { for { select { case num := <-ch1: fmt.Println("num=", num) ch2 <- 100 } } }() for { select { case num := <-ch2: fmt.Println("num=", num) ch1 <- 300 } } }
死锁4:读取空channel 死锁
func main() { // 死锁1 ch := make(chan int)js //close(ch)编程 向关闭的channel中读取数据 是该数据的类型的零值 num := <-ch fmt.Println("num=", num) }
死锁5:超过channel缓存继续写入数据导致死锁
func main() { ch := make(chan int, 2) ch <- 1 ch <- 2 ch <- 3 num := <-ch fmt.Println("num=", num) }
死锁6:向已关闭的channel中写入数据不会导致死锁,但是回出发panic异常
func main() { ch := make(chan int, 2) close(ch) ch <- 1 num := <-ch fmt.Println("num=", num) }
到此这篇关于golang channel死锁的几种情况小结的文章就介绍到这了,更多相关Golang channel 死锁内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论