为了账号安全,请及时绑定邮箱和手机立即绑定

使用信号量解决死锁错误时出现致命错误

使用信号量解决死锁错误时出现致命错误

Go
慕森卡 2022-06-27 10:46:33
我正在学习围棋。我正在尝试使用信号量解决 goroutine 上的死锁问题。我创建了两个写入无缓冲通道的函数。阅读正在主频道上进行。第三个功能应该关闭通道。当我运行程序时,它会抛出这个错误致命错误:所有goroutines都睡着了 - 死锁!有人可以向我解释为什么这不起作用。import (    "fmt"    "sync")var wg sync.WaitGroupvar s = []string{"a", "b", "c", "d"}var w = []string{"w", "x", "t", "z", "p"}func f(c chan string, ch chan bool) {    for _, word := range s {        c <- word    }    fmt.Println("f about to exit")    ch <- true    wg.Done()}func g(c chan string, ch chan bool) {    for _, word := range w {        c <- word    }    fmt.Println("g about to exit")    ch <- true    wg.Done()}func f1(ch chan string, c chan bool) {    <-c    <-c    fmt.Println("about to close channel")    close(ch)}func main() {    ch := make(chan string)    c := make(chan bool)    wg.Add(3)    go f(ch, c)    go g(ch, c)    go f1(ch, c)    for word := range ch {        fmt.Println(word)    }    wg.Wait()}
查看完整描述

2 回答

?
www说

TA贡献1775条经验 获得超8个赞

您应该在命名数据通道和信令通道时保持一致。

就这样。


这里有两个生产者 go 例程和一个消费者 go 例程,

所以让我先简化您的代码,在线尝试:


func main() {

    ch := make(chan string)

    done := make(chan struct{})

    go func() {

        for _, word := range []string{"1", "2", "3"} {

            ch <- word

        }

        done <- struct{}{}

    }()

    go func() {

        for _, word := range []string{"10", "20", "30", "40"} {

            ch <- word

        }

        done <- struct{}{}

    }()

    go func() {

        <-done

        <-done

        close(ch)

    }()

    for word := range ch {

        fmt.Print(word, " ")

    }

    fmt.Println()

}

输出:


1 2 10 3 20 30 40 

笔记:

  1. 您不需要sync.WaitGroup,因为 done 通道足以发送信号。

  2. 空结构足以发出信号。

  3. 收到两个 done 信号后,您可以关闭数据通道,因此 main 退出循环。


查看完整回答
反对 回复 2022-06-27
?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

启动三个 goroutine 后,您从通道读取ch直到ch关闭。所有函数都ch作为它们写入的第一个参数,但f1写入它的第二个参数,而不是第一个参数。也就是说,f1正在写入cmain 中的通道,因此f1在第一次写入时被阻止,因为没有人在读取c. 主 goroutine 被阻止读取,ch因为在完成之后fg没有人写入它。

这看起来像是通道命名混乱:两个函数 get (c, ch),一个 gets (ch, c),但都用 调用(ch, c)


查看完整回答
反对 回复 2022-06-27
  • 2 回答
  • 0 关注
  • 107 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信