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

我们如何确定 Go 中“最后一个”工作进程/线程何时完成?

我们如何确定 Go 中“最后一个”工作进程/线程何时完成?

Go
一只甜甜圈 2022-01-10 15:15:15
我将使用一个 hacky 低效的素数查找器来使这个问题更加具体。假设我们的 main 函数触发了一堆“worker”goroutine。他们会将结果报告给打印它们的单个通道。但并不是每个工人都会报告一些事情,所以我们不能使用计数器来知道最后一个工作何时完成。或者有什么办法吗?对于具体的例子,在这里,main 触发 goroutine 以检查值 2...1000 是否为素数(是的,我知道它效率低下)。package mainimport (    "fmt"    "time")func main() {    c := make(chan int)    go func () {        for {            fmt.Print(" ", <- c)        }    }()    for n := 2; n < 1000; n++ {        go printIfPrime(n, c)    }    time.Sleep(2 * time.Second)   // <---- THIS FEELS WRONG}func printIfPrime(n int, channel chan int) {    for d := 2; d * d <= n; d++ {        if n % d == 0 {            return        }    }    channel <- n}我的问题是我不知道如何在正确的时间可靠地停止它。我尝试在末尾添加一个 sleepmain并且它可以工作(但它可能需要太长时间,而且这不是编写并发代码的方法!)。我想知道是否有办法通过通道或其他方式发送停止信号,以便main在正确的时间停止。这里的诀窍是我不知道会有多少工人响应。这是不可能的还是有一个很酷的技巧?(如果这个主要示例有答案,那就太好了。我可能可以概括。或者可能没有。也许这是特定于应用程序的?)
查看完整描述

1 回答

?
MMMHUHU

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

使用WaitGroup.


以下代码使用两个 WaitGroup。main 函数用于wgTest等待print_if_prime函数完成。完成后,它会关闭通道以中断打印 goroutine 中的 for 循环。主要功能用于wgPrint等待打印完成。


package main


import (

  "fmt"

  "sync"


func main() {

  c := make(chan int)

  var wgPrint, wgTest sync.WaitGroup


  wgPrint.Add(1)

  go func(wg *sync.WaitGroup) {

    defer wg.Done()

    for n := range c {

        fmt.Print(" ", n)

    }

  }(&wgPrint)


  for n := 2; n < 1000; n++ {

    wgTest.Add(1)

    go print_if_prime(&wgTest, n, c)

  }


  wgTest.Wait()

  close(c)

  wgPrint.Wait()

}


func print_if_prime(wg *sync.WaitGroup, n int, channel chan int) {

  defer wg.Done()

  for d := 2; d*d <= n; d++ {

    if n%d == 0 {

        return

    }

  }

  channel <- n

}


查看完整回答
反对 回复 2022-01-10
  • 1 回答
  • 0 关注
  • 235 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号