首页 文章 golang-channel造成死锁案例

golang-channel造成死锁案例

来源:https://blog.csdn.net/qq_26105397/article/details/123386958 发布时间:2022-01-18 15:39:46 作者:Soul-Yang 阅读量:264
 1. 案例1,无缓冲信道导致死锁, -> 运行死锁
  // 不设定容量创建的是无缓冲信道,在接收者未准备好之前信道处于阻塞状态,
package main
 
func main(){
    // 例如本案例:fatal error: all goroutines are asleep - deadlock!
// sch := make(chan string)
// sch <- "string"
// fmt.Println(<-sch)
 
// 处理方法,使用双协程,并且接收者在发送者就绪之前,-> 运行正常
// sch := make(chan string)
//
// go func() {
// fmt.Println(<-sch) // 接收者就绪
// }()
//
// sch <- "string"
       // time.Sleep(time.Second)
}

  2.案例2,改用有缓冲的信道, -> 运行正常

package main
 
func main() {
 
// 案例2,改用有缓冲的信道, -> 运行正常
// sch := make(chan string, 1)
// sch <- "hello"
// fmt.Println(<-sch)
 
// 有缓冲信道导致的死锁,因信道容量满了,再向信道添加数据会产生阻塞,后续无法消费,从而导致死锁  - >运行死锁
// sch := make(chan string, 1)
// sch <- "hello"
// sch <- "world" // 因信道满了,无法接收数据从而产生阻塞
// fmt.Println(<-sch)
 
// 解决方法,生产者跟消费者区分开来,使用不同的协程
sch := make(chan int, 1)
go func() {
count := 0
for {
sch <- count
count++
}
close(sch) // 生产者不再生产消息,关闭掉通道即可
}()
go func() {
for {
fmt.Println(<-sch)
}
}()
select {}
}

  3. 案例3,消费者一直空等待,并无生产者再生产消息,导致程序阻塞产生死锁 -> 运行死锁

package main
 
func main() {
 
// 案例3,消费者一直空等待,并无生产者再生产消息,导致程序阻塞产生死锁  -> 运行死锁
// pipLine := make(chan string)
// go func() {
// pipLine <- "hello world"
// pipLine <- "hello China"
// }()

// // 再无消息消费,造成另一方无穷等待,造成死锁
// // fatal error: all goroutines are asleep - deadlock!
// for data := range pipLine {
// fmt.Println(data)
// }
 
// 解决方法
// 生产者不再生产消息时,关掉该信道,从而避免消费者傻等待造成死锁
go func() {
pipLine <- "hello world"
pipLine <- "hello China"
close(pipline)
}()
 
select {}
}
  4.案例4,无缓冲通道,当消费者结束,生产者也应该有检测机制,发现消费者没了,应该停止生产,并关闭掉通道,否则会造成死锁,如下代码:
package main
 
import (
"fmt"
)
 
var index uint64 = 0
 
func main() {
 
// 案例4,无缓冲通道,当消费者结束,生产者也应该有检测机制,发现消费者没了,应该停止生产,并关闭掉通道,否则会造成死锁,如下代码:
// fatal error: all goroutines are asleep - deadlock!
sch := make(chan uint64)
go func() {
count := 0
for {
if count == 10 {
// break // 消费者退出,会造成死锁
}
fmt.Println("read = ", <-sch)
count++
// time.Sleep(time.Second)
}
}()
 
go func() {
for {
index++
if index == 10 {
index = 0
}
sch <- index
// time.Sleep(time.Second)
}
}()
 
// 处理方法,生产消费必须同时存在,或者消费者推出,生产者能感知,并且主动关闭掉通道
// 主程
select {}
}






  
留言
https://blog.key9.cn/
用户登录
您还没有写任何评论内容!
您已经评论过了!
只能赞一次哦!
您已经收藏啦!