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

所有goroutine完成后,让golang关闭使用的频道

杜成和
2023-03-14
问题内容

我正在尝试运行许多goroutine,这些例程会将其结果提供给某个渠道。我需要一种好的方法来在所有goroutine完成后让通道关闭。

我的第一个尝试是在产生所有go例程之后关闭它,但是我认为以某种方式在所有goroutine可以发送结果之前关闭通道。

for i:=0; i<=10;i++{
  go func(){
    result:=calculate()
    c<-result
  }()
}
close(c)
for result:= range c{
  all_result=append(all_result, result...)
}

然后,我第二次尝试计算一个线程,并在没有线程运行后将其关闭。

for i:=0; i<=10;i++{
  go func(){
    atomic.AddUint64(&go_routine_count, 1)
    result:=calculate()
    c<-result
    atomic.AddUint64(&rt_count, ^uint64(0))
  }()
}
go func(){
  for{
    // some little time to let above goroutine count up go_routine_count before this goroutine can actually check go_routine_count==0
    time.Sleep(time.Millisecond)
    go_current_routine_count:=atomic.LoadUint64(&go_routine_count)
    if go_routine_count==0{
      close(c)
    }
  }
}()
for result:= range c{
  all_result=append(all_result, result...)
}

它可行,但我认为可能有更正确或更有效的方法。同样,在某种情况下,如果稍​​后的计数检查goroutine在goroutines循环之前运行,则此方法将不起作用。

有没有更好的办法?


问题答案:

sync.WaitGroup类型应封装您要执行的操作,而无需睡眠呼叫或忙于等待。它使您可以等待任意数量的任务,而不必担心它们完成的顺序。

以您的原始示例为例,您可以将其更改为使用等待组,如下所示:

var wg sync.WaitGroup
for i:=0; i<=10;i++{
    wg.Add(1)
    go func(){
        result:=calculate()
        c<-result
        wg.Done()
    }()
}
// Close the channel when all goroutines are finished
go func() {
    wg.Wait()
    close(c)
}()
for result:= range c{
    all_result=append(all_result, result...)
}


 类似资料:
  • 问题内容: 这是我的代码段。 现在做完之后 我要在这里实现的是,我要等待线程池中的所有线程完成执行,然后关闭执行器。 但是我想这不是这里正在发生的事情。主线程似乎正在执行关闭,它只是关闭了所有内容。 在我的线程池大小为2之前,我做了以下事情,而且似乎可行。 我如何在线程池中使用更多线程?谢谢。 问题答案: 您通常使用以下成语: 只是说执行者不会接受新工作。 等待直到所有已提交的任务完成它们的工作(

  • 问题内容: 该代码选择同一文件夹中的所有xml文件,作为被调用的可执行文件,并以异步方式将处​​理应用于回调方法中的每个结果(在下面的示例中,仅打印文件名)。 如何避免使用sleep方法阻止main方法退出?我在解决问题时遇到了麻烦(我想这就是同步结果所必需的),因此,我们将不胜感激! 问题答案: 您可以使用sync.WaitGroup。引用链接的示例:

  • 问题内容: 我在不是要连续运行的脚本中使用猫鼬,而且我面对的似乎是一个非常简单的问题,但我找不到答案。简单地说,只要我调用将请求发送到mongodb的任何mongoose函数,我的nodejs实例就不会停止,而我必须使用Ctrl + c或Program.exit()手动将其杀死。 该代码大致如下所示: 我尝试将调用添加到mongoose.disconnect(),但没有结果。除此之外,一切都很好(

  • 在一个实用程序库中,我正在创建一个执行器服务 然后,主线程将向该服务发布一些任务。当主线程完成时,我想关闭Executor服务,以允许应用程序退出。 问题是我只能更改实用程序库中的代码。我考虑的一个选项是使用守护线程。但在发布到该服务的任务完成之前,它会突然关闭。

  • 问题内容: 看一下这个人为的例子: 该程序的输出将仅为“ This will print”。goroutine的输出并且不会被发出,因为我想函数线程将在goroutines甚至有机会开始执行之前完成。 使类似的代码在Golang中工作并且不提前终止的惯用方式是什么? 问题答案: 最简单,最干净和“可扩展”的方法是使用: 输出(在Go Playground上尝试): 执行以下操作时要遵循的简单“规则

  • 视频处理完成后的回调 当处理完毕视频后(上传、转码、审核都完成后),Spark 平台会通过由上传接口入参 notify_url 指定的 HTTP/HTTPS 地址以 GET 方式发起回调。若用户网站地址使用HTTPS协议进行数据安全传输时,用户需保证其拥有的CA证书是合法的。 用户指定的 notify_url 符合以下四种 notify_url 格式之一即为合法: 1、http://domain