在 Golang 中防止 main() 函数在 goroutine 完成之前终止

2023-12-25

看看这个人为的例子:

package main

import "fmt"

func printElo() {
    fmt.Printf("Elo\n")
}

func printHello() {
    fmt.Printf("Hello\n")
}

func main() {
    fmt.Printf("This will print.")
    i := 0
    for i < 10 {
        go printElo()
        go printHello()
        i++
    }
}

该程序的输出只是“This will print”。 Goroutine 的输出printElo() and printHello不会被发射,因为,我猜,main()函数线程将在 goroutine 有机会开始执行之前完成。

让类似的代码在 Golang 中工作并且不会提前终止的惯用方法是什么?


最简单、最干净且“可扩展”的方法是使用sync.WaitGroup https://golang.org/pkg/sync/#WaitGroup:

var wg = &sync.WaitGroup{}

func printElo() {
    defer wg.Done()
    fmt.Printf("Elo\n")
}

func printHello() {
    defer wg.Done()
    fmt.Printf("Hello\n")
}

func main() {
    fmt.Printf("This will print.")
    i := 0
    for i < 10 {
        wg.Add(1)
        go printElo()
        wg.Add(1)
        go printHello()
        i++
    }
    wg.Wait()
}

输出(尝试一下去游乐场 https://play.golang.org/p/6L64RRPEW1):

This will print.Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo

执行此操作时要遵循的简单“规则”sync.WaitGroup:

  • call WaitGroup.Add() https://golang.org/pkg/sync/#WaitGroup.Add在“原始”goroutine(开始一个新的)之前go https://golang.org/ref/spec#Go_statements陈述
  • 建议致电WaitGroup.Done() https://golang.org/pkg/sync/#WaitGroup.Done延迟,所以即使 Goroutine 发生恐慌,它也会被调用
  • 如果你想通过WaitGroup对于其他函数(并且不使用包级变量),您必须传递一个指向它的指针,否则WaitGroup(这是一个结构)将被复制,并且Done()在副本上调用的方法不会在原始版本上观察到
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Golang 中防止 main() 函数在 goroutine 完成之前终止 的相关文章

  • 对象锁定私有类成员 - 最佳实践? (爪哇)

    I asked 类似的问题 https stackoverflow com questions 10548066 multiple object locks in java前几天 但对回复不满意 主要是因为我提供的代码存在一些人们关注的问题
  • 如何确定 go 中当前运行的可执行文件的完整路径?

    我一直在 osx 上使用这个函数 Shortcut to get the path to the current executable func ExecPath string var here os Args 0 if strings H
  • 在 .NET 并发线程之间传递数据的最佳方式是什么?

    我有两个线程 一个需要轮询一堆单独的静态资源以查找更新 另一种需要获取数据并将其存储在数据库中 线程1如何告诉线程2有东西要处理 如果数据块是独立的 则将数据块视为要由线程池处理的工作项 使用线程池和QueueUserWorkItem将数据
  • 时间:2019-03-17 标签:c++fstream并发访问

    如果从不同的进程 线程同时访问文件会发生什么 据我所知 没有锁定文件的标准方法 只有操作系统特定的功能 就我而言 文件将被经常读取而很少写入 现在如果A打开一个文件进行读取 ifstream 并开始读取块 和B打开相同的文件进行写入 ofs
  • Golang 中的确定性 RSA 加密 - 如何在多次加密下为给定消息获得相同的结果

    对于下面的RSA加密代码 每次对同一条消息进行加密时 结果都会不同 我发现这是由于rand Reader in the rsa EncryptOAEP功能使其更加安全doc https pkg go dev crypto rsa Encry
  • golang.org 包和标准库之间的区别

    我使用 go 已经有一段时间了 我注意到 Go 标准库 和 golang org x 之间存在重复的包 我的问题是 为什么它们被释放两次 在这两者中 我应该使用哪一个 更新的 规范的等 到目前为止我注意到的一些示例包已发布两次 golang
  • 什么是竞争条件?

    编写多线程应用程序时 最常见的问题之一是竞争条件 我向社区提出的问题是 竞赛条件是什么 你如何检测它们 你如何处理它们 最后 如何防止它们发生 当两个或多个线程可以访问共享数据并且它们试图同时更改它时 就会出现竞争条件 由于线程调度算法可以
  • 将产生 goroutine 的 golang 方法

    据我所知 如果 goroutine 太忙 它们会阻止其他 goroutine 运行 对我来说 这意味着我的应用程序的性能和响应能力可能取决于我知道哪些库方法将控制其他 goroutine 例如通常是 Read 和 Write 有什么方法可以
  • 我们如何在 Go 中使用通道来代替互斥锁?

    通道将通信 值的交换 与同步相结合 保证两个计算 goroutine 处于已知状态 如何使用 Google Go 中的通道来执行互斥量的功能 package main import sync var global int 0 var m s
  • 使用泛型:类型参数 T 不能与 == 进行比较

    我正在操场上玩 Go Generics 尝试编写一些通用数组函数 https gotipplay golang org p vS7f Vxxy2j https gotipplay golang org p vS7f Vxxy2j packa
  • 执行 SELECT 或 INSERT

    我想写一些类似的东西CASE以我想要的方式在 PostgreSQL 中声明SELECT从表中 如果什么也没找到 我想INSERT改为放入表中 我的示例表allocated ideas看起来像这样 challenge id user id i
  • 什么是“非阻塞”并发?它与普通并发有何不同?

    什么是 非阻塞 并发 它与使用线程的普通并发有何不同 为什么不在所有需要并发的场景中都使用非阻塞并发呢 使用非阻塞并发有开销吗 我听说Java中可以实现非阻塞并发 我们是否应该在特定场景下使用此功能 将这些方法之一与集合一起使用是否有区别或
  • Haskell 中多核编程的现状如何?

    Haskell 中多核编程的现状如何 现在有哪些项目 工具和库可用 有哪些经验报道 2009年至2012年期间 发生了以下事件 2012 从 2012 年开始 并行 Haskell 状态更新开始出现在并行 Haskell 摘要 http w
  • 当一种语言是另一种语言的平行超集时,这意味着什么?

    我正在阅读关于实时并发 C 的期刊文章 http link springer com article 10 1007 2FBF00365999 并且它在摘要中提到 因此你们中的任何人都可以通过该链接查看上下文 Concurrent C 是
  • Java 中的 LRU 缓存实现

    我看过下面的代码 我认为addElement方法的实现中有一个无用的while循环 它永远不应该有比 size 1 更多的元素 因为已经有一个写锁 那么为什么 addElement 方法会删除元素直到它达到这个条件 真的 while con
  • 如何对结构切片而不是切片结构进行范围调整

    稍微玩了一下 Go HTML 模板后 我发现的所有循环模板中对象的示例都是将切片结构传递给模板 有点像这个示例 type UserList struct Id int Name string var templates template M
  • 无论线程如何,对象是否总是能看到其最新的内部状态?

    假设我有一个带有简单整数计数变量的可运行对象 每次可运行对象运行时该变量都会递增 该对象的一个 实例被提交以在计划的执行程序服务中定期运行 class Counter implements Runnable private int coun
  • golang中如何将相对路径解析为绝对路径?

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

    参考 java util concurrent 包和 Future 接口 我注意到 除非我弄错了 只有 SwingWorker 实现类才能启动冗长的任务并能够查询进度 这就引出了以下问题 有没有办法在非 GUI 非 Swing 应用程序 映
  • 如何在 Go 中获取给定月份的第一个星期一?

    我正在尝试获取给定月份的第一个星期一 我能想到的最好方法是循环前 7 天 然后返回 Weekday Monday 有一个更好的方法吗 通过查看时间的 Weekday 您可以计算出第一个星期一 package main import fmt

随机推荐

  • 使用 opengrok 搜索历史记录

    我一直在使用 OPENGROK 来搜索我的 SVN 代码存储库 它需要存储库的签出版本来为其建立索引 当我在我的系统上签出版本时 我已经能够实现通过存储库进行搜索 当我尝试搜索存储库的历史记录时 我陷入了困境 我能做些什么 另外 如何更新索
  • Windows 7中uwsgi安装错误

    尝试根据安装uwsgi文档 http uwsgi docs readthedocs org en latest tutorials Django and nginx html我在 Windows 7 上收到以下错误 我应该怎么办 uwsgi
  • 无法在 JavaScript 中创建 Vue Router 实例

    下列的导游 https router vuejs org en essentials getting started html我到达了需要创建 Vue 实例的地步 这似乎有效 但是 我还需要在 Vue 的构造函数中提供一个 Vuew Rou
  • 每次按下灌木丛时按下都会生成草药

    我在 2D 游戏中从森林中的一些灌木丛中生成了一个香草集合 我的脚本具有克隆 Herbs 预制件的功能 但当我按下灌木丛时没有任何反应 这里有什么问题 Script using System Collections using System
  • 从另一个 data.frame 填充 data.frame 中的缺失值

    我有一个带有行和列名称的 N x M 数据框 DF1 其中许多值都是 NA 还有第二个数据框 DF2 1 x M 因此实际上可能是一个向量 其行名称与 DF1 相同 我想使用 DF2 来填充 DF1 列中的缺失值 任何帮助将非常感激 Udp
  • IBM Data Server Client v9.7fp5 的日期时间字段溢出

    使用 EntityFramework v4 1 和 IBM 数据服务器客户端v9 7fp5 DB 首先根据预定义的具有 DATE 列的 DB2 表生成代码 DB2 DATE 列在代码生成期间映射到 NET DateTime 数据类型 当尝试
  • 如何在 mysql 中使用 UPDATE 自动声明行或资源

    我有一个资源表 比如说汽车 我想以原子方式声明它 然后我想要有关我刚刚声明的资源的信息 如果每个用户只能使用一种资源 我可以采取以下技巧 UPDATE cars SET user bob WHERE user IS NULL LIMIT 1
  • 如何在 iOS OpenGL ES 2.0 中绘制星星

    这个问题以前就被问过 但在我的搜索中是好几年前的事了 答案始终是使用纹理映射 但我真正想做的是将星星表示为单个顶点 你可能认为我正在使用一种简单的方法 但事实上 单点光源实际上看起来相当不错和现实的 但我想用高斯模糊之类的东西来处理那个光点
  • xcode 8 beta 3:预期的“,”连接多子句条件的一部分

    在 xcode 8 beta 3 中收到新警告 此语法有什么问题 或者 xcode 中是否存在错误 SwiftyJSON swift 772 35 预期的 连接多子句条件的一部分 if let errorValue error where
  • 使用 for 循环反转数组没有任何作用[重复]

    这个问题在这里已经有答案了 我试图使用 for 循环反转 15 个数字的数组 但由于某种原因数组顺序保持不变 我的代码如下所示 int main int arr 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • Hibernate 无法添加或更新子行:外键约束失败

    当我尝试将对象保存到数据库中时出现错误 java sql SQLIntegrityConstraintViolationException Cannot add or update a child row a foreign key con
  • Backbone.history.start() 阻止后退按钮离开页面

    我现在在一些应用程序上遇到了这个问题 所以我想知道我是否对 Backbone 历史记录做错了什么 情况是这样的 我有两页 比方说 index html app html 索引页只是一个普通的 平面的 HTML 页面 带有一个链接app ht
  • Google 跟踪代码管理器延迟了 window.load?

    我有一个页面在加载时触发 ajax 调用 window load function updateDeliverySlots 我的顶部还有 Google 跟踪代码管理器 javascriptbody 我知道当前的建议是将其放在head部分 但
  • gmail api 对于特定标签返回总邮件数为 0

    我一直在使用 获取标签 API 来获取特定标签的详细信息 直到最后几天一切都正常 我现在观察到 消息总数 计数始终为 0 未读消息 计数正确显示 我已经在我的应用程序中使用了它 并且也尝试过https developers google c
  • Carrierwave / Fog / S3“不是公认的存储提供商”

    我有一个使用 Carrierwave 进行文件上传的 Rails 应用程序 它一直运行良好 但我想开始使用 Amazon S3 进行图像存储 我收到此错误 ArgumentError is not a recognized storage
  • 通过字符串winforms获取资源项

    在 C Winforms 应用程序中 如何访问Resources通过字符串 例如我知道我可以做Properties Resources MyImage但是 直到运行时我才知道我需要哪个图像 包含一个字符串 MyImage 我怎样才能访问Pr
  • Azure 表存储、WCF 服务和枚举

    这是我的问题 定义订单的类有一个属性称为PaymentStatus 这是一个enum定义如下 public enum PaymentStatuses int OnDelivery 1 Paid 2 Processed 3 Cleared 4
  • Angular 5/1.x 混合应用程序可以支持 HMR 吗?

    The 记录在案 https github com angular angular cli wiki stories configure hmr使用 Angular 5 应用程序配置 HMR 的方法不适用于混合 Angular 5 1 x
  • 如何读取蓝牙特性并将其从字节数据转换为正确的值(Bluetooth for flutter)

    我必须使用与 Flutter 结合使用的 BLE 蓝牙低功耗 来读取和写入一些值到 Bike Smart 训练器中 当我尝试从 GATT 特征 org bluetooth characteristic supported power ran
  • 在 Golang 中防止 main() 函数在 goroutine 完成之前终止

    看看这个人为的例子 package main import fmt func printElo fmt Printf Elo n func printHello fmt Printf Hello n func main fmt Printf