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

golang 中合并排序的递归/并行实现中出现死锁

WBOY
发布: 2024-02-10 13:15:08
转载
437 人浏览过

golang 中合并排序的递归/并行实现中出现死锁

php小编西瓜发现,在golang中使用递归或并行实现合并排序时,有可能出现死锁的问题。合并排序是一种常用的排序算法,可以有效地将一个大数组分解成多个小数组进行排序,然后再合并起来。然而,在golang的并发编程中,如果不注意控制goroutine之间的同步,就有可能导致死锁的情况发生。本文将详细探讨这个问题,并提供解决方案。

问题内容

我正在尝试了解有关 Golang 中并发性的更多信息,因此我正在尝试改进 MergeSort 算法以同时进行排序。

我的想法是每次将数组一分为二时创建一个 goroutine,所以我的代码如下:

func mergeSort(arr []int) []int {
    if len(arr) <= 1 {
        return arr
    }

    mid := len(arr) / 2
    left := arr[:mid]
    right := arr[mid:]

    orderedLeft := make(chan []int)
    orderedRight := make(chan []int)

    var wg sync.WaitGroup

    wg.Add(2)
    go func() {
        defer wg.Done()

        left = mergeSort(left)
        orderedLeft <- left
    }()

    go func() {
        defer wg.Done()
        right = mergeSort(right)
        orderedRight <- right
    }()

    wg.Wait()

    close(orderedLeft)
    close(orderedRight)

    left = <-orderedLeft
    fmt.Println(left)
    right = <-orderedRight
    fmt.Println(right)

    return merge(left, right)
}
登录后复制

但是我遇到了致命错误:

fatal error: all goroutines are asleep - deadlock!
登录后复制

我做错了什么?

解决方法

可能会有点混乱,因为您混合了两种并发模式。我一会儿就到。

当您使用无缓冲通道时,发送方 Goroutine 将阻塞,直到接收方 Goroutine 准备好接收值。 在这种情况下,主 Goroutine 正在等待两个 Goroutines 使用 wg.Wait() 完成,而两个 Goroutine 正在尝试将其结果发送到通道 orderedLeftorderedRight。但是,由于主 goroutine 没有主动从通道接收这些值,因此 goroutine 会被阻塞并且无法继续完成。

您可以通过缓冲通道来轻松解决此问题: orderedRight := make(chan []int, 1)

但是,您可以使用通道或 waitGroups 而不是混合使用它们,在这种情况下这并不是必需的:

func mergeSort(arr []int) []int {
    if len(arr) <= 1 {
        return arr
    }

    mid := len(arr) / 2
    left := arr[:mid]
    right := arr[mid:]

    var wg sync.WaitGroup

    wg.Add(2)
    go func() {
        defer wg.Done()
        left = mergeSortWg(left)
    }()

    go func() {
        defer wg.Done()
        right = mergeSortWg(right)
    }()

    wg.Wait()

    return merge(left, right)
}
登录后复制

以上是golang 中合并排序的递归/并行实现中出现死锁的详细内容。更多信息请关注PHP中文网其他相关文章!

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