下面两个代码为何一个会死锁一个不会?

来源:1-14 Go 并发编程最佳实践

落笔锋

2021-07-06 22:53:01

针对chan的多人写一人读的场景
如果把读端放主协程 就提示死锁

func main() {
   ch := make(chan int, 4)
   wg := sync.WaitGroup{}
   wg.Add(2)
   go func() {
      defer wg.Done()
      for i := 0; i < 4; i++ {
         ch <- i
      }
   }()
   go func() {
      defer wg.Done()
      for i := 0; i < 4; i++ {
         ch <- i
      }
   }()

   for v := range ch {
      fmt.Println(v)
   }
   wg.Wait()
   close(ch)
   time.Sleep(time.Second)
}

如果把读端单独放一个goroutine里就不会死锁?

func main() {
	ch := make(chan int, 4)
	wg := sync.WaitGroup{}
	wg.Add(2)
	go func() {
		defer wg.Done()
		for i := 0; i < 4; i++ {
			ch <- i
		}
	}()
	go func() {
		defer wg.Done()
		for i := 0; i < 4; i++ {
			ch <- i
		}
	}()

	go func() {
		for v := range ch {
			fmt.Println(v)
		}
	}()
	wg.Wait()
	close(ch)
	time.Sleep(time.Second)
}

想了解下哪些状况会死锁, 有点脑壳痛. 不清楚哪些情况会死锁. 能简单指导下吗 或者给一些实例代码

写回答

1回答

Xargin

2021-07-06

第一个例子你把 wg.Wait 放在单独的一个 goroutine 里并且关闭 ch 就行了

package main

import "fmt"
import "sync"
import "time"

func main() {
	ch := make(chan int, 4)
	wg := sync.WaitGroup{}
	wg.Add(2)
	go func() {
		defer wg.Done()
		for i := 0; i < 4; i++ {
			ch <- i
		}
	}()
	go func() {
		defer wg.Done()
		for i := 0; i < 4; i++ {
			ch <- i
		}
	}()

	go func() {
		wg.Wait()
		close(ch)
	}()
	for v := range ch {
		fmt.Println(v)
	}
	time.Sleep(time.Second)
}


0
hccundefined
回复
hargin
hp>? 我明白了,感谢

h021-07-10
共5条回复

Go高级工程师实战营

慕课网与 GoCN 社区官方联手打造,定义行业Go高级人才培养标准,4个月,快速晋升为P6+/D7级高级人才。

458 学习 · 266 问题

查看课程