同步Go例程有什么需要

时间:2018-09-16 07:08:15

标签: go goroutine routines

此特定的 Go 代码使用一个频道来同步goroutines

// We can use channels to synchronize execution
// across goroutines. Here's an example of using a
// blocking receive to wait for a goroutine to finish.

package main

import "fmt"
import "time"

// This is the function we'll run in a goroutine. The
// `done` channel will be used to notify another
// goroutine that this function's work is done.
func worker(done chan bool) {
   fmt.Print("working...")
   time.Sleep(time.Second)
   fmt.Println("done")

   // Send a value to notify that we're done.
   done <- true
}

func main() {

   // Start a worker goroutine, giving it the channel to
   // notify on.
   done := make(chan bool, 1)
   go worker(done)

   // Block until we receive a notification from the
   // worker on the channel.
   <-done
 }

需要同步goroutines吗?我们不是以交错方式运行goroutine的想法。为什么我们要在两个或多个go例程之间引入同步?是用于回调吗?

谢谢

2 个答案:

答案 0 :(得分:4)

并发不是凭空发生的。出于多种原因,可能需要对启动的goroutine进行协调。在这种情况下,有一个主要的(除了示例之外,还被设计为演示):

  • 如果到达main方法的结尾,则Go运行时将退出。届时,正在运行的程序(包括所有其他goroutine)将被终止。这里的协调确保子goroutine在允许程序退出之前已经停顿。

    昨天我写了一个这样的例子:https://stackoverflow.com/a/52347990/1113760

您可能会想到许多其他原因,这些原因需要在并发工作之间进行协调(此列表并非特定于Go且并非详尽无遗):

  • goroutine在共享内存区域上运行,因此需要以互斥的形式进行协调,以确保一次只有一个例程可以访问关键部分。

  • 您的继续处理可能取决于多个goroutine的输出,因此您在继续协商之前等待共识。

  • 您的程序可能会提供服务,并且您要确保在关闭之前,所有正在进行的请求(在单独的goroutine中处理)都已完成并耗尽。

这个问题超出了Go的范围,它不考虑与并发执行相关的计算机科学难题,以及在其中有用的实例,因此文献将有更多详细信息和示例。

答案 1 :(得分:0)

如果进程可以独立运行,那么事情就很简单了。我们可以在核心中运行每个流程,事情会很容易。问题取决于流程是否相关(即流程A取决于流程B)。

实现此目标的经典方法是共享一个公共内存并对其进行锁定,以便只有一个进程才能在给定的时间访问它。转到频道采用了不同的方法,您可以在此处了解更多信息