首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >围棋:如何将狗、猫和鱼交替打印3次,不死锁3次?

围棋:如何将狗、猫和鱼交替打印3次,不死锁3次?
EN

Stack Overflow用户
提问于 2022-05-01 11:15:49
回答 1查看 51关注 0票数 -4

1.如何利用sync.WaitGroup解决死锁问题?

我的代码可以正确地打印结果,但是它会导致死锁。

我现在能想到的是:将sync.WaitGroup替换为time.Sleep。

但是我想知道如何使用sync.WaitGroup来解决死锁?

  1. 这是运行的结果:

代码语言:javascript
复制
dog: 0
cat: 0                                                           
fish: 0                                                          
dog: 1                                                           
cat: 1                                                           
fish: 1                                                          
dog: 2                                                           
cat: 2                                                           
fish: 2                                                          
fatal error: all goroutines are asleep - deadlock!               
                                                                 
goroutine 1 [semacquire]:                                        
sync.runtime_Semacquire(0xeaeeb0)                                
        D:/GoSDK/go1.17.3/src/runtime/sema.go:56 +0x25           
sync.(*WaitGroup).Wait(0x60)                                     
        D:/GoSDK/go1.17.3/src/sync/waitgroup.go:130 +0x71    

  1. 这是我的代码:

代码语言:javascript
复制
func main(){
    wg := sync.WaitGroup{}
    wg.Add(3)
    const Count = 3
    ch1, ch2, ch3 := make(chan bool), make(chan bool), make(chan bool)

    go func() {
        defer wg.Done()
        for i := 0; i < Count; i++ {
            <-ch1
            fmt.Println("dog:", i)
            //notice 2
            ch2 <- true
        }
    }()
    go func() {
        defer wg.Done()
        for i := 0; i < Count; i++ {
            //wait 1
            <-ch2
            fmt.Println("cat:", i)
            //notice 3
            ch3 <- true
        }
    }()
    go func() {
        defer wg.Done()
        for i := 0; i < Count; i++ {
            //wait 2
            <-ch3
            fmt.Println("fish:", i)
            //notice 1
            ch1 <- true
        }
    }()
    //notic 1
    ch1 <- true
    wg.Wait()
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-01 11:37:29

这里的问题是,没有go例程在等待ch1。因此,在第三个goroutine锁(ch1 <- true)的最后一次迭代中。所以你需要的是一种方法来认识到这条链停止了。我简短而谦逊的建议:

代码语言:javascript
复制
func main() {
    wg := sync.WaitGroup{}
    wg.Add(3)
    const Count = 3
    ch1, ch2, ch3 := make(chan bool), make(chan bool), make(chan bool)
    chainEnded := make(chan struct{})

    go func() {
        defer wg.Done()
        for i := 0; i < Count; i++ {
            <-ch1
            fmt.Println("dog:", i)
            //notice 2
            ch2 <- true
        }
        chainEnded <- struct{}{}
    }()
    go func() {
        defer wg.Done()
        for i := 0; i < Count; i++ {
            //wait 1
            <-ch2
            fmt.Println("cat:", i)
            //notice 3
            ch3 <- true
        }
    }()
    go func() {
        defer wg.Done()
        for i := 0; i < Count; i++ {
            //wait 2
            <-ch3
            fmt.Println("fish:", i)
            //notice 1
            ch1 <- true
        }
    }()
    //notic 1
    ch1 <- true
    <-chainEnded // wait for the loop to end and send to this chan
    <-ch1        // unblock the attempt to chain of the last routine
    wg.Wait()
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72076194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档