死锁-所有的goroutine都处于休眠状态(即使使用等待组)

g2ieeal7  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(124)

我正在学习go并发,我希望两个go例程在通过通道沿着更新值的同时保持相互通信。一个人把这个数加2,而另一个人减1。代码和输出如下:
这个代码有什么问题吗?

package main

import (
    "fmt"
    "sync"
    "time"
)

var wg sync.WaitGroup

func addTwo(r chan int, e chan int) {
    val := <-r
    fmt.Println("AT Recieved: ", val)
    time.Sleep(1 * time.Second)
    e <- val + 2
}

func subtractOne(r chan int, e chan int) {
    val := <-r
    fmt.Println("SO Recieved: ", val)
    time.Sleep(1 * time.Second)
    e <- val - 1
}

func main() {
    ch := make(chan int)
    ch2 := make(chan int)

    wg.Add(1)
    go addTwo(ch, ch2)

    wg.Add(1)
    go subtractOne(ch2, ch)

    ch <- 1
    wg.Wait()

}

输出量:

AT Recieved:  1
SO Recieved:  3
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [semacquire]:
sync.runtime_Semacquire(0x4b2de8?)
    /usr/lib/go-1.18/src/runtime/sema.go:56 +0x25
sync.(*WaitGroup).Wait(0x0?)
    /usr/lib/go-1.18/src/sync/waitgroup.go:136 +0x52
main.main()

然后它就消失了
为什么goroutines不会永远交换值,即使我没有在goroutines中调用wg.done()?

bvuwiixz

bvuwiixz1#

你启动的两个goroutine都只接收一个值,发送一个值,然后结束。从那里开始,只有main goroutine,在wg.Wait()被阻塞,因为你从来没有调用wg.Done()
你忘了使用(n endless)循环:

func addTwo(r chan int, e chan int) {
    for {
        val := <-r
        fmt.Println("AT Recieved: ", val)
        time.Sleep(1 * time.Second)
        e <- val + 2
    }
}

func subtractOne(r chan int, e chan int) {
    for {
        val := <-r
        fmt.Println("SO Recieved: ", val)
        time.Sleep(1 * time.Second)
        e <- val - 1
    }
}

通过此更改,您的应用将永远运行,输出为:

AT Recieved:  1
SO Recieved:  3
AT Recieved:  2
SO Recieved:  4
AT Recieved:  3
SO Recieved:  5
AT Recieved:  4
....

相关问题