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

goroutine之间的死锁

羿经武
2023-03-14
问题内容

我是新手。当我注释掉第二个goroutine时,出现致命错误。我不明白是什么原因导致此错误发生。你能跟我解释一下吗?

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int)
    go func() { 
        for i := 0; i < 10; i++ {
            ch <- i
        }
    } ()
    // go func() { 
        for {
            if num, ok := <-ch; !ok {
                break
            } else {
                fmt.Printf("%d\n", num)
            }
        }
    // } ()
    time.Sleep(2 * time.Second)
    close(ch)
}

这将输出以下代码

0
1
2
3
4
5
6
7
8
9
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
    /tmp/sandbox169127128/main.go:17 +0xa0

Program exited.

问题答案:

ch从发送goroutine接收到所有值之后,receive的for循环块将在接收时被阻塞。运行时检测到程序被卡住并出现紧急情况。

解决方法是在发送所有值后关闭通道:

go func() { 
    for i := 0; i < 10; i++ {
        ch <- i
    }
    close(ch)
} ()

在闭路接收产生值0, false。for循环的接收会中断false值。

close(ch)从程序末尾删除。

在操场上跑。



 类似资料:
  • 本小节将通过goroutine的创建,消亡,阻塞和恢复等过程,来观察Go语言的调度策略,这里就称之为生老病死吧。整个Go语言的调度系统是比较复杂的,为了避免结构体M和结构体P引入的其它干扰,这里主要将注意力集中到结构体G中,以goroutine为主线。 goroutine的创建 前面讲函数调用协议时说过go关键字最终被弄成了runtime.newproc。这就是一个goroutine的出生,所有新

  • 问题内容: 我有以下设置: 我正在创建黄瓜步骤,我需要能够启动和关闭该应用程序。 问题答案: 您可以使用和频道杀死无限循环! 很不错的Go交换,不是吗? 现在,这有什么奇怪的地方?这是一个零尺寸的频道。我们只能用空结构填充它(即:)。可能是a 或其他,因为我们不使用频道的内容。重要的是,我们使用通道通知goroutine中的无限循环,该该停止了。 该语句用于捕获来自渠道的内容。这是一条阻塞语句(除

  • 本文向大家介绍Golang中Goroutine和Thread之间的区别。,包括了Golang中Goroutine和Thread之间的区别。的使用技巧和注意事项,需要的朋友参考一下 古鲁丁 Goroutine是可以与其他goroutine一起独立执行的方法/功能。Go语言中的每个并发活动通常都称为gorountine。 线 线程是一个轻量级的过程。可以将其视为执行一段代码的单元。操作系统管理线程。

  • 问题内容: 对于我的要求之一,我必须创建N个工作程序例程,该例程将由一个监视程序监视。所有工作程序完成后,监视程序必须结束。我的代码以死锁结尾,请帮忙。 问题答案: 您的monitorWorker永不死。当所有工作人员完成时,它将继续等待cs。这将导致死锁,因为其他任何东西都不会继续发送给CS,因此wg永远不会达到0。一种可能的解决方法是,当所有工作程序完成时,让监视器关闭通道。如果for循环在m

  • 问题内容: 我想编写三个同时发送整数的并发go例程。现在,我的代码已正确编译,但是在第一次执行后,出现错误“所有goroutine都处于睡眠状态- 死锁!”。我试图找到错误,但是在代码逻辑中找不到任何错误。有人可以帮助我在我的代码中查找错误。我的代码如下。提前致谢。 谁能告诉我为什么我将Routine2和Routine3声明为go例程,为什么输出为[no output]。我是GO语言的新手,据我从

  • 我在更新和插入查询之间的应用程序中遇到了死锁,我无法理解为什么以导致死锁的方式给出锁。 null 插入- null