了解 Go 通道死锁

2024-02-20

package main

import (
    "fmt"
    "time"
)

func main() {
    p := producer()
    for c := range p {
        fmt.Println(c)
    }
}

func producer() <-chan string {
    ch := make(chan string)
    go func() {
        for i := 0; i < 5; i++ {
            ch <- fmt.Sprint("hello", i)
            time.Sleep(1 * time.Second)
        }
        // commented the below to show the issue
        // close(ch)
    }()
    return ch
}

运行上面的代码将打印 5 条消息,然后给出“all goroutine are sleep - deadlock error”。我知道如果我关闭通道,错误就会消失。

我想了解的是 go 运行时如何知道代码将在通道上无限等待并且没有其他任何东西会将数据发送到通道中。

现在,如果我向 main() 函数添加一个额外的 go 例程..它不会抛出任何错误并继续在通道上等待。

go func() {
        for {
            time.Sleep(2 * time.Millisecond)
        }
    }()

那么这是否意味着...... go 运行时只是寻找正在运行的 go 例程是否存在,该例程可能会将数据发送到通道中,因此不会引发死锁错误?


如果您想更深入地了解 Go 如何实现死锁检测,请查看代码中抛出以下错误的位置:"all goroutines are asleep - deadlock!": https://github.com/golang/go/blob/master/src/runtime/proc.go#L3751 https://github.com/golang/go/blob/master/src/runtime/proc.go#L3751

看起来 Go 运行时对有多少个 goroutine、有多少个空闲 goroutine 以及有多少个 goroutine 正在休眠以获取锁进行了一些相当简单的统计(不确定通道 I/O 上的哪个休眠会增加)。在任何给定时间(与其余运行时序列化),它只是执行一些算术并检查是否all - idle - locked > 0...如果是这样,那么程序仍然可以取得进展...如果它是0,那么你肯定陷入了僵局。

您可以通过无限循环防止 goroutine 休眠来引入活锁(就像您在实验中所做的那样,显然运行时对计时器的休眠处理不一样)。在这种情况下,运行时将无法检测到死锁,并且会永远运行。

此外,我不确定运行时到底何时检查死锁 - 进一步检查谁调用了它checkdead()如果您有兴趣,可能会在那里产生一些见解。

免责声明 - 我不是 Go 核心开发者,我只是在电视上玩过一个 :-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解 Go 通道死锁 的相关文章

  • 解组转义 XML

    在 Go 中 我将如何解码此 XML 响应 我尝试过建立一个自定义UnMarshal方法在我的Answerstruct 但我运气不太好
  • 为什么我不能将左大括号放在下一行?

    当我尝试编译以下代码时遇到奇怪的错误 package main import fmt fmt func main var arr 3 int for i 0 i lt 3 i fmt Printf d arr i 错误如下 unexpect
  • Golang中按长度分割字符串

    有谁知道如何在 Golang 中按长度分割字符串 例如 每 3 个字符分割 helloworld 那么理想情况下它应该返回一个 hel low orl d 数组 或者 一个可能的解决方案是在每 3 个字符后附加一个换行符 所有的想法都非常感
  • os.Mkdir 和 os.MkdirAll 权限

    我正在尝试在程序开始时创建一个日志文件 我需要检查是否 log如果不创建目录 则目录存在 然后继续创建日志文件 好吧 我尝试使用os Mkdir 也os MkdirAll 但无论我在第二个参数中输入什么值 我都会得到一个没有权限的锁定文件夹
  • RSA OAEP、Golang 加密、Java 解密 -BadPaddingException:解密错误

    我正在尝试解密使用 RSA OAEP 在 Golang 中加密的字符串 但出现 BadPaddingException 解密错误 很难弄清楚我错过了什么 这是Golang加密方法 func encryptString rootPEM io
  • 如何为所有 API 端点全局设置 http.ResponseWriter Content-Type 标头?

    我是 Go 新手 现在正在用它构建一个简单的 API package main import encoding json fmt github com gorilla mux github com gorilla handlers log
  • 与通道相比,sync.WaitGroup 的优势是什么?

    我正在开发一个并发 Go 库 我偶然发现了 goroutine 之间两种不同的同步模式 其结果相似 等待组 https play golang org p ZYPLlcp16TZ package main import fmt sync t
  • 是否可以在 C/C++ 中模仿 Go 接口?

    在 Go 中 如果类型具有接口定义的所有方法 则可以将其分配给该接口变量 而无需显式继承它 是否可以在 C C 中模仿此功能 是的 您可以使用纯抽象类 并使用模板类来包装 实现 抽象类的类型 以便它们扩展抽象类 这是一个简单的示例 incl
  • 错误:标准包中非标准导入“gopkg.in/yaml.v2”

    我正在尝试从以下位置导入 go yamlhttps github com go yaml yaml https github com go yaml yaml 并且我发现了一个 Google 没有提供帮助的错误 I ran go get g
  • golang无法启动调试,显示未找到框架CoreFoundation

    我使用的是 Macbook pro m1 在数据迁移或更新到 monterey 后 不确定是什么原因导致的 golang 似乎无法调试或 go list 编译 我尝试重新安装 更新 golang 结果是一样的 Go版本 1 17 3 dar
  • 单值上下文中的多值错误

    我在编译 GO 代码时遇到此错误 multiple value fmt Println in single value context 我正在尝试创建一个函数 该函数接受可变数量的整数并将每个变量打印在一行上 GO package main
  • GoLang 中的 HTML 部分

    我刚刚开始使用 Go 我想用它创建一个网络应用程序 我现在尝试的是以handlebarsjs 式的方式使用模板 我想将页眉和页脚从主页中取出 以便可以将它们注入到每个网页上 我当前的设置应该是解析主页 页眉和页脚 HTML 文件并缓存它们
  • 有没有办法间歇性地执行重复性任务?

    有没有办法在 Go 中执行重复的后台任务 我在想类似的事情Timer schedule task delay period 在爪哇 我知道我可以用 goroutine 来做到这一点Time sleep 但我想要一些容易停止的东西 这是我得到
  • 使用泛型:类型参数 T 不能与 == 进行比较

    我正在操场上玩 Go Generics 尝试编写一些通用数组函数 https gotipplay golang org p vS7f Vxxy2j https gotipplay golang org p vS7f Vxxy2j packa
  • 为什么 DER ASN.1 大整数的解组在 Golang 中仅限于 SEQUENCE?

    我希望能够使用encoding asn1 包从 DER 文件中解组一个大整数 但它看起来只适用于整数序列 例如 这不起作用 这很奇怪 因为 Big Int 的编组效果很好 https play golang org p Wkj0jAA6bp
  • 运行最新版本时没有“最新”消息?

    我正在尝试使用Sparkle https sparkle project org与 Qt Go 的绑定 https github com therecipe qt app 闪光 m import
  • 如何使用 go1.6.2 构建 linux 32 位

    有没有任何组合GOARCH and GOOS我可以设置哪些值来构建 ELF 32 位二进制文 件 GOOS linux and GOARCH 386 更多示例 架构 32 bit gt GOARCH 386 64 bit gt GOARCH
  • Golang const unsafe.Sizeof

    不明白为什么我可以做到 const OK uint64 0 const OK int unsafe Sizeof uint64 0 但不是这个 const NOK binary Size uint64 0 它的解释在规格 https gol
  • 如何在golang中获得两个切片的交集?

    Go 中有没有有效的方法来获取两个切片的交集 我想避免嵌套 for 循环之类的解决方案slice1 string foo bar hello slice2 string foo bar intersection slice1 slice2
  • golang中如何将相对路径解析为绝对路径?

    节点中是否有类似 path resolve 的API 或者有什么东西可以做同样的事情 例如 nodejs代码 path resolve sample sh 应该得到 home currentuser sample sh 解决 表示用户主目录

随机推荐

  • 反向柯里化?

    我想以某种方式组合函数 请考虑伪代码 而不是 F 中的这 2 个函数 F1 x y F2 F1 10 note I did not specify arguments for F1 reverse curry for lack of a b
  • 使用指针功能 - 1 个设备上的 2 个独立应用程序

    我前段时间问过这个问题如何使用主应用程序和引导加载程序中的一项功能 嵌入 https stackoverflow com questions 45459776 how can i use one function from main app
  • 来自图像选择器 swift 3 的 GeoTag 图像

    我想从图像选择器中选择的图像获取地理标记位置 我正在使用这个代码 if picker sourceType UIImagePickerControllerSourceType PhotoLibrary if let currentLat p
  • 根据属性以及 javascript 中的计数对对象数组进行分组

    我有一系列对象说temp 我想根据对象的属性进行分组 例如 应该对性别进行分组 并计算其数量 const temp properties id 1234 gender male status Active properties id 145
  • R 中的 set.seed() 和 .Random.Seed()

    我正在参加模拟课程 但我无法理解 R 中的 Random seed 我知道我们使用 set seed 以便模拟是可重现的 它本质上是我们的 PRNG 的初始值 有人可以向我解释 Random seed 的作用以及它为什么重要吗 例如我什么时
  • 如何允许匿名用户访问 MVC 中的某个给定页面?

    我已在 ASP NET MVC Web 应用程序中启用表单身份验证 我想允许匿名用户仅访问某些特定页面 例如 Register cshtml 通过这样做 我能够允许从我的根 web config 访问我的 CSS 文件
  • Jquery步骤->按钮单击->转到步骤

    我正在使用jquery步骤 http www jquery steps com ASP NET 应用程序中的向导 单击按钮时更改步骤的事件出现问题 file js 中的初始化步骤 var WizardFunc function var wi
  • jquery 文件上传 在一篇文章中发送所有文件

    我正在使用 jquery 文件上传 我在项目中的多个页面中使用它 对于一个项目 我需要在一个请求中上传所有文件 因为我循环遍历所有图像 然后创建并关闭一份档案 我认为一次性发送所有图像比更改服务器端处理程序更快 唯一的问题是 我无法让他们在
  • 在 Windows Sharepoint Services 3.0 中仅编辑拥有的列表项

    有没有办法限制 WSS 3 0 中的 编辑项目 权限 仅允许用户编辑自己的文档或列表项目 我们需要用户能够仅编辑他创建的文档 列表项目 而不是其他人创建的项目 因此 本质上我们需要 EDIT 权限和 ADD 权限的子集 这在 Windows
  • 如何将 csv 添加到 cassandra 数据库?

    我知道这可以用传统方式完成 但是如果我要使用 Cassandra DB 是否有一种简单 快速且灵活的方法将 csv 作为一组键值对添加到数据库中 能够通过 CSV 文件添加时间序列数据是我的首要要求 我可以切换到任何其他数据库 例如 mon
  • JQUERY 如何在拖动时禁用不允许的光标?

    我遇到了不允许的光标问题 拖动 拖动 元素时 出现不允许的光标 我无法再拖动它 我怎样才能防止这种情况发生 我想让我的 拖动 元素在鼠标按下时始终为 绝对 注意 我知道它可能因为 指针事件 而发生 但我需要将它包含在这段代码中 一些代码 d
  • 为 MVC2 AsyncController 构建单元测试

    我正在考虑将我的一些 MVC 控制器重写为异步控制器 我对这些控制器进行了工作单元测试 但我试图了解如何在异步控制器环境中维护它们 例如 目前我有这样的操作 public ContentResult Transaction do stuff
  • Bootstrap 3 Modal:如何使用 jquery/javascript 检查模式是否打开或关闭

    谁能告诉我如何检查 bootstrap 3 0 模式状态 它是使用 jQuery 或 javascript 打开还是关闭 我使用了以下代码 但当您打开模式一次时它会起作用 否则会出现数据未定义错误 if addMemberModal dat
  • 我在 C 中遇到超过时间限制的错误。如何克服它?

    c 性能分析时间限制编写该程序的目的的详细信息在链接上给出 https www spoj com problems CRCLE UI https www spoj com problems CRCLE UI 并且错误超过时间限制 inclu
  • JSF/RichFaces:条件文本样式

    我有一个可以是或否的字符串 在 Java 支持 bean 的对象中实例化 我似乎无法找到根据 JSF 是否从 bean 分别获得 是 或 否 来有条件地将文本设置为红色或绿色的最佳方法 我正在使用 richfaces 但我应该使用
  • 查找包括隐藏和折叠节点的逻辑子节点

    我尝试找到这个问题的答案 在我发现的每一篇文章中都有一个递归查找子项的答案 但它们都不适用于隐藏或折叠的子项 此外 在每一篇文章中 都有人问这是否可能 但没有人回答 所以我开始认为这是不可能的 如果有人有办法做到这一点 我将永远感激不已 我
  • SimpleDateFormat 解析 2 月 29 日的日期错误 [重复]

    这个问题在这里已经有答案了 我有这个有线 public static boolean isFirstDayOfMonth String format String value SimpleDateFormat sdf new SimpleD
  • 如何删除所有没有任何关系的节点 - neo4j/cypher

    我正在 neo4j 数据库中生成节点 并希望删除那些没有关系的节点 执行此操作的最佳密码指令是什么 Try MATCH n WHERE size n 0 DELETE n
  • 在 Firebase 中存储 id 列表

    我不知道如何用 firebase 解决这个问题 我有用户 每个用户都有帖子 每个帖子都有一个由 firebase 生成的 id 如何将这些 id 存储在用户节点中 我正在使用字符串 连接它们 在我的 js 应用程序中解析它们 基本上将它们视
  • 了解 Go 通道死锁

    package main import fmt time func main p producer for c range p fmt Println c func producer lt chan string ch make chan