-4

这个特定的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
 }

同步 goroutine 需要什么?不是我们将以交错方式运行 goroutine 的想法吗?为什么我们要在两个或多个 goroutine 之间引入同步?是为了回调吗?

谢谢

4

2 回答 2

4

并发不会在真空中发生。出于多种原因,可能需要协调您启动的 goroutine。在这种情况下,有一个主要的(在示例之外,这是为了演示而设计的):

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

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

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

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

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

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

这个问题超出了围棋的范围,考虑了与并发执行相关的计算机科学困难,以及它有用的实例,因此文献将有更多的细节和例子。

于 2018-09-16T09:18:38.607 回答
0

如果进程可以独立运行,那么事情就很简单了。我们可以在一个核心中运行每个进程,事情就会变得简单。当进程依赖时(即进程 A 依赖于进程 B),就会出现问题。

实现这一点的经典方法是共享一个公共内存并将其锁定,以便在给定时间只有一个进程可以访问它。Go 频道采用不同的方法,您可以在此处阅读有关它的更多信息

于 2018-09-21T17:15:14.380 回答