首页 > 后端开发 > Golang > 正文

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

PHPz
发布: 2024-02-09 13:40:08
转载
1117 人浏览过

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

php小编小新在这里为大家介绍一种常见的并发编程问题——死锁。死锁是指所有goroutine都进入了睡眠状态,即使使用了等待组等机制,也无法继续执行下去。这种情况下,所有的goroutine都无法向前推进,导致程序陷入无限等待的状态。在并发编程中,避免死锁是非常重要的,我们需要了解其原因和解决方案,以确保程序的正常运行。

问题内容

我正在学习 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()
登录后复制

然后它就退出了。

为什么 goroutine 不会永远交换值,即使我没有在 goroutine 中调用 wg.done() ?

解决方法

您启动的两个 goroutine 都只接收一个值并发送一个值,然后结束。从那里开始,只有 main goroutine,在 wg.wait() 处被阻止,因为你从未调用 wg.done()

你忘记使用(n无限)循环:

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
....
登录后复制

以上是死锁 - 所有 goroutine 都处于睡眠状态(即使使用等待组)的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:stackoverflow.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!