go sync wait group deadlock死锁问题

go sync  wait group死锁问题,请看下面代码,看起来是没有任何问题的,如果INWait .Add(1)和INWait.Done()都能执行到并且REWait .Add(1)和REWait.Done()也能执行到的情况那肯定是没有问题的.

但是如果在outCh函数中加个return那就出问题了,go run  -race  xxx.go执行一下,REWait .Add(1)和REWait.Done()不相等,一直阻塞,造成死锁,程序无法退出。

所以开发中waitGroup  Add()后立马就延时执行defer Done()即可避免wait group 死锁问题

package main
import (
	"fmt"
	"sync"
	"time"
)
var (
	INWait = sync.WaitGroup{}//写入等待
	REWait = sync.WaitGroup{}//读取等待
)

func main() {
	start := time.Now().UnixNano() / 1e6 //毫秒
	fmt.Println("开始时间", start)

	chanNum := 100
	ch := make(chan int, chanNum)
	defer close(ch) //延时关闭chan

	for i := 0; i < chanNum; i++ {
		go inCh(ch, i) //开启N个协程写入chan
	}

	for i := 0; i < 100; i++ {
		go outCh(ch, i) //开启N个协程读取chan
	}

	INWait.Wait() //等待写入管道的锁完毕
	REWait.Wait() //等待读取管道的锁完毕

	end := time.Now().UnixNano()/1e6 - start
	fmt.Println("数据读取完毕,消耗时间毫秒", end)
}

func inCh(ch chan int, i int) {
	INWait.Add(1)
    //defer INWait.Done()//避免死锁
	ch <- i
	INWait.Done()//注销这行,在add的时候直接defer done
}

func outCh(ch chan int, i int) {
	REWait.Add(1)
    //defer REWait.Done()//这样就不会死锁了
	val, ok := <-ch //读取到数据和值
	if val%10 == 0 && ok {
        if i > 80 {
			//return//开启后,下面的REWait.Done()是无法运行的,出现死锁
		}
		fmt.Println(i, "读取到chan的数据才会执行到这里", val)
	}
	REWait.Done()//注销这行,在add的时候直接defer done
}

 

并发时候保证公共数据安全问题加锁问题注意事项https://blog.csdn.net/qq_27517377/article/details/114824259

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值