记录一个golang select的问题sync.runtime_Semacquire(0xc0000aa018)

文章目录

    • 代码
    • 错误如下
    • 解决过程

代码

功能是生产10个数据,消费10个数据,可以边生产边消费

type Book struct {
	Num       chan int
	Mutex     sync.Mutex
	waitGroup *sync.WaitGroup
	End       chan bool
	Isclosed  bool
}
func main() {
	n := 10
	b := &Book{
		Num:       make(chan int, n),
		waitGroup: new(sync.WaitGroup),
		End:       make(chan bool,1),
	}
	wg := sync.WaitGroup{}
	wg.Add(n)
	go Produce(n, b)
	go Consumer3(b, &wg)
	wg.Wait()
}
// 生产10个数据
//
func Produce(n int, b *Book) {
	for i := 0; i < n; i++ {
		b.Num <- i
		fmt.Println("put ", i)
	}
	b.End <- true
}
func Consumer3(b *Book, wg *sync.WaitGroup) {
	//for{
		select {
		case v := <-b.Num:
			fmt.Println("get ", v)
			wg.Done()
		case <-b.End:
			return
		default:
			fmt.Println("do")
		}
	//}
}

错误如下

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc0000aa018)
        /usr/local/go/src/runtime/sema.go:56 +0x42
sync.(*WaitGroup).Wait(0xc0000aa010)
        /usr/local/go/src/sync/waitgroup.go:130 +0x64
main.main()
        /Users/huanglin/go/src/gostep/thirdParty/goroutine/test.go:37 +0x153

Process finished with exit code 2

解决过程

网上大致搜了下,一个版本是说goroutine都跑完了,但主gouroutine还在等待,看了那个问题,是传了wg的副本进行wg.Done操作,我试着修改成指针,还是一样的问题,
后来做了一次尝试,在select外加了一层for循环,问题解决,

func Consumer3(b *Book, wg *sync.WaitGroup) {
	for{
		select {
		case v := <-b.Num:
			fmt.Println("get ", v)
			wg.Done()
		case <-b.End:
			return
		default:
			fmt.Println("do")
		}
	}
}

可能是和select的机制有关,问题是解决了,但为什么还是不清楚,先放在这里,了解了select的原理再更新

你可能感兴趣的:(golang脱坑笔记)