搜索
首页后端开发Golang终止无限循环 goroutine 的安全方法?

终止无限循环 goroutine 的安全方法?

问题内容

我有一个充当侦听器的 goroutine。输入流传入某个缓冲的 channel,我希望我的 goroutine 处理传入该通道的数据。然而,有时 channel 可能会暂时没有数据输入。如果 channel 一秒钟没有什么可提供的,我希望我的 goroutine 做一些不同的事情。该函数如下所示:

func main () {
    var wg sync.WaitGroup
    arr := make([]*myObject, 0)
    wg.Add(1)
    go listener(c, arr, &wg)
    for {
        // sending stuff to c
    }
}

func listener(c chan *myObject, arr []*myObject, wg *sync.WaitGroup) {
    for {
        select {
        case value := <- c:
            arr = append(arr, value)
        case <- time.After(1 * time.Second):
            fmt.Println(arr)
        }
}

问题是我想看到通过该通道的所有内容都打印出来。如果 main 突然结束,可能 arr 中还剩下一些东西还没有打印出来,我就看不到了。所以我需要确保这个goroutine在程序结束之前处理完通道中的所有数据。我认为,这意味着我需要使用 WaitGroup 并使用 Wait() 来确保程序在我的 goroutine 完成需要执行的操作之前不会关闭。 但我不知道在我的 WaitGroup 上调用 Done() 的位置。

基本上,我需要一种安全的方法来在程序结束之前“暂停”goroutine,并打印出剩下的内容。我怎样才能做到这一点?

更糟糕的是,对于单元测试之类的事情,我自己将数据发送到通道,在发送一定数量后,我想查看数组。但是,如果我只是在将数据发送到通道的代码之后立即检查数组,则 goroutine 可能还没有机会处理所有数据。在这种情况下,我想等待 goroutine 处理我发送的所有数据,然后我想暂停它并要求它向我显示数组。但我如何知道 goroutine 何时完成处理呢?我可以 sleep 一段时间,给它一个完成的机会,然后停下来看看,但这感觉相当黑客。我认为有一个最佳实践方法可以解决这个问题,但我还没有弄清楚。

这是我的一些想法,其中零个有效。

  1. 在无限 for 循环之外调用 Done()。这不起作用,因为据我所知,该代码无法访问。

  2. 在超时case中调用Done()。这是行不通的,因为超时后可能会有更多数据在路上,我希望我的 goroutine 继续监听。


正确答案


修改侦听器以在通道关闭时返回。返回时调用 wg.Done():

func listener(c chan *myObject, arr []*myObject, wg *sync.WaitGroup) {
    defer wg.Done()
    for {
        select {
        case value, ok := <- c:
            if !ok { return }
            arr = append(arr, value)
        case <- time.After(1 * time.Second):
            fmt.Println(arr)
        }
}

修改 main 以在发送完成后关闭通道。在从 main 返回之前等待 goroutine 完成。

var wg sync.WaitGroup
arr := make([]*myObject, 0)
wg.Add(1)
go listener(c, arr, &wg)
for {
    // sending stuff to c
}
close(c)
wg.Wait()

以上是终止无限循环 goroutine 的安全方法?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:stackoverflow。如有侵权,请联系admin@php.cn删除
使用GO编程语言构建可扩展系统使用GO编程语言构建可扩展系统Apr 25, 2025 am 12:19 AM

goisidealforbuildingscalablesystemsduetoitssimplicity,效率和建筑物内currencysupport.1)go'scleansyntaxandaxandaxandaxandMinimalisticDesignenhanceProductivityAndRedCoductivityAndRedCuceErr.2)ItSgoroutinesAndInesAndInesAndInesAndineSandChannelsEnablenableNablenableNableNablenableFifficConcurrentscorncurrentprogragrammentworking torkermenticmminging

有效地使用Init功能的最佳实践有效地使用Init功能的最佳实践Apr 25, 2025 am 12:18 AM

Initfunctionsingorunautomationbeforemain()andareusefulforsettingupenvorments和InitializingVariables.usethemforsimpletasks,避免使用辅助效果,andbecautiouswithTestingTestingTestingAndLoggingTomaintAnainCodeCodeCodeClarityAndTestesto。

INIT函数在GO软件包中的执行顺序INIT函数在GO软件包中的执行顺序Apr 25, 2025 am 12:14 AM

goinitializespackagesintheordertheordertheyimported,thenexecutesInitFunctionswithinApcageIntheirdeFinityOrder,andfilenamesdetermineTheOrderAcractacractacrosmultiplefiles.thisprocessCanbeCanbeinepessCanbeInfleccessByendercrededBydeccredByDependenciesbetenciesbetencemendencenciesbetnependendpackages,whermayleLeadtocomplexinitialitialializizesizization

在GO中定义和使用自定义接口在GO中定义和使用自定义接口Apr 25, 2025 am 12:09 AM

CustomInterfacesingoarecrucialforwritingFlexible,可维护,andTestableCode.TheyEnableDevelostOverostOcusonBehaviorBeiroveration,增强ModularityAndRobustness.byDefiningMethodSigntulSignatulSigntulSignTypaterSignTyperesthattypesmustemmustemmustemmustemplement,InterfaceSallowForCodeRepodEreusaperia

在GO中使用接口进行模拟和测试在GO中使用接口进行模拟和测试Apr 25, 2025 am 12:07 AM

使用接口进行模拟和测试的原因是:接口允许定义合同而不指定实现方式,使得测试更加隔离和易于维护。1)接口的隐式实现使创建模拟对象变得简单,这些对象在测试中可以替代真实实现。2)使用接口可以轻松地在单元测试中替换服务的真实实现,降低测试复杂性和时间。3)接口提供的灵活性使得可以为不同测试用例更改模拟行为。4)接口有助于从一开始就设计可测试的代码,提高代码的模块化和可维护性。

在GO中使用init进行包装初始化在GO中使用init进行包装初始化Apr 24, 2025 pm 06:25 PM

在Go中,init函数用于包初始化。1)init函数在包初始化时自动调用,适用于初始化全局变量、设置连接和加载配置文件。2)可以有多个init函数,按文件顺序执行。3)使用时需考虑执行顺序、测试难度和性能影响。4)建议减少副作用、使用依赖注入和延迟初始化以优化init函数的使用。

GO的选择语句:多路复用并发操作GO的选择语句:多路复用并发操作Apr 24, 2025 pm 05:21 PM

go'SselectStatementTreamLinesConcurrentProgrambyMultiplexingOperations.1)itallowSwaitingOnMultipleChannEloperations,执行thefirstreadyone.2)theDefirstreadyone.2)thedefefcasepreventlocksbysbysbysbysbysbythoplocktrograpraproxrograpraprocrecrecectefnoopeready.3)

GO中的高级并发技术:上下文和候补组GO中的高级并发技术:上下文和候补组Apr 24, 2025 pm 05:09 PM

contextancandwaitgroupsarecrucialingoformanaginggoroutineseflect.1)context contextsallowsAllowsAllowsAllowsAllowsAllingCancellationAndDeadLinesAcrossapibiboundaries,确保GoroutinesCanbestoppedGrace.2)WaitGroupsSynChronizeGoroutines,确保Allimizegoroutines,确保AllizeNizeGoROutines,确保AllimizeGoroutines

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具