当前位置: 首页 > 面试题库 >

为什么我的golang频道会引发死锁错误?

郎宣
2023-03-14
问题内容
package main

import (
    "fmt"
    "sync"
)

func push(c chan int,wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int,wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result,ok := <- c
        fmt.Println(result,ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c,wg)
    go pull(c,wg)

    wg.Wait()
}

输出:

localhost:src kuankuan$ go run goroutine.go 
0 true
1 true
2 true
3 true
4 true
throw: all goroutines are asleep - deadlock!

goroutine 1 [semacquire]:
sync.runtime_Semacquire(0x42130100, 0x42130100)
    /usr/local/go/src/pkg/runtime/zsema_amd64.c:146 +0x25
sync.(*WaitGroup).Wait(0x42120420, 0x0)
    /usr/local/go/src/pkg/sync/waitgroup.go:79 +0xf2
main.main()
    /Users/kuankuan/go/src/goroutine.go:31 +0xb9

goroutine 2 [syscall]:
created by runtime.main
    /usr/local/go/src/pkg/runtime/proc.c:221
exit status 2

问题答案:

之所以陷入僵局,是因为结构是通过值而不是通过引用传递的。

将WaitGroup传递给函数时,需要传递 指针 而不是值。否则,将使用WaitGroup的副本。

这是您的工作示例:

package main

import (
    "fmt"
    "sync"
)

func push(c chan int,wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int,wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result,ok := <- c
        fmt.Println(result,ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c,&wg)
    go pull(c,&wg)

    wg.Wait()
}


 类似资料:
  • 死锁描述了另外两个线程因为永远等待对方而被阻塞的情况。当死锁发生时,程序永远挂起,你唯一能做的就是杀死程序。 为什么在下面给出的示例生产者-消费者问题中没有发生死锁: 我想知道为什么当同步对象正在等待其他线程释放锁时,在同步块中调用等待方法不会导致死锁?

  • 我正在做一个编码练习:给定一个整数序列作为一个数组,确定是否可以通过从数组中删除不超过一个元素来获得严格递增的序列。 所以我写了这段代码: 现在,这段代码似乎适用于大多数序列,但这段代码引发了一个错误: 错误如下: 我只是不明白列表索引怎么可能超出范围…有人有线索吗?

  • 问题内容: 由于以下代码中的某种原因,我收到“致命错误:所有goroutine都在睡眠-死锁!”。我正在使用应该不阻塞的缓冲通道。不知道我在做什么错 游乐场链接https://play.golang.org/p/J9meD5aKna 问题答案: 虽然您的解决方案可能会起作用,但我对此并不满意。 首先,您需要更改通道大小以使其起作用这一事实表明存在潜在的问题/错误。现在,每次您要启动另一个时,都必须

  • 问题内容: 在过去的几天里,我一直在尝试通过重构我的一个命令行实用程序来在Golang中进行并发,但是我被困住了。 这是原始代码(master分支)。 这是并发分支(x_concurrent分支)。 当我使用执行并发代码时,如果将JIRA问题添加到此处的通道,则永不执行,这将导致我永远挂起。 我的想法是,我有大量的JIRA问题,我想为每个goroutine编写一个goroutine,以查看是否需要

  • 这似乎与对象没有被实例化有关,尽管我不太明白为什么。有人知道出什么事了吗?

  • 我的MySQL表出现死锁。只涉及一个表,我可以始终如一地复制它。只有当我有多个线程运行代码时才会发生这种情况。 下面是表格: 然后,我在每个线程中运行这2个查询,每个线程具有不同的user_id值。 需要注意的是,当调用DELETE语句时,数据库中从不存在user_id X。正在使用运行这些查询的代码位创建新用户。然而,该函数允许我修改用户的帐户,因此,从旧用户的团队中删除现有的角色。 所以,当足