问题标签 [goroutine]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
8214 浏览

go - 去并发访问指针方法

我试图了解当您对指针方法进行并发访问时会发生什么?

我有一个指针映射并产生了一些 go 例程。我将地图传递给每个 goroutine,每个 goroutine 将使用地图中的一个值。没有任何东西被写入地图,只是被读取。

地图很小,只有 4 个键,因此可能不止一个 go 例程会使用地图中的相同值。

问题是,当两个 go 例程调用同一个指针的方法时会发生什么?我会得到不可预测的结果吗?

编辑

示例:我正在取出地图部分,因为这不是我想要的问题。

我有foowhich 是一个类型的指针,MyStruct这个结构有一个DoSomething带参数的方法。在main函数中,我创建了两个go routines,它们都调用foo.DoSomething传递不同的值。在这个例子中,第一个 go 例程比第二个例程要执行更大的计算(这里只使用睡眠时间来模拟计算)。同样,结构中没有任何变化我只是调用结构方法。foo.DoSomething当第一个 go 例程仍在使用该方法时,我是否必须担心第二个 go 例程会调用该方法?

0 投票
2 回答
90 浏览

for-loop - go 中循环和 goroutinues 的意外行为

为什么会这样:

打印 012

而这:

打印 333?

0 投票
5 回答
65056 浏览

go - 如何在不使用 time.Sleep 的情况下等待所有 goroutines 完成?

此代码选择同一文件夹中的所有 xml 文件作为调用的可执行文件,并对回调方法中的每个结果进行异步处理(在下面的示例中,仅打印出文件名)。

如何避免使用 sleep 方法来防止 main 方法退出?我在处理频道时遇到问题(我认为这就是同步结果所需要的),因此感谢您的帮助!

0 投票
4 回答
31503 浏览

go - 如何使用 goroutine 池

我想使用 Go 从 Yahoo Finance 下载股票价格电子表格。我将在其自己的 goroutine 中为每只股票发出一个 http 请求。我有一个大约 2500 个符号的列表,但我宁愿一次发出 250 个请求,而不是并行发出 2500 个请求。在 Java 中,我会创建一个线程池并在线程空闲时重用它们。我试图找到类似的东西,一个 goroutine 池,如果你愿意的话,但找不到任何资源。如果有人能告诉我如何完成手头的任务或为我指出相同的资源,我将不胜感激。谢谢!

0 投票
2 回答
8840 浏览

go - 在 http 处理程序中使用 Goroutines 进行后台工作

我以为我找到了一种简单的方法来立即返回一个 http 响应,然后在后台做一些工作而不会阻塞。但是,这不起作用。

它第一次工作 - 立即返回响应并开始后台工作。但是,任何进一步的请求都会挂起,直到后台 goroutine 完成。有没有更好的方法来做到这一点,它不涉及设置消息队列和单独的后台进程。

0 投票
1 回答
442 浏览

concurrency - Go并发和通道混乱

我是 Go 新手,在理解并发和通道时遇到了问题。

程序的输出是:

但我认为应该只有一行:

所以在 main 函数中,<-c 正在阻塞它并等待另外两个 go rountines 向通道发送数据。一旦 main 函数从 c 接收到数据,它应该继续并退出。

display 和 sum 同时运行并且 sum 需要更长的时间,因此 display 应该将 true 发送到 c 并且程序应该在 sum 完成之前退出......

我不确定我是否清楚地理解它。有人可以帮我解决这个问题吗?谢谢!

0 投票
5 回答
30303 浏览

multithreading - 您将如何定义要立即执行的 goroutine 池?

TL;DR:请直接到最后一部分,告诉我你将如何解决这个问题。

今天早上我开始使用来自 Python 的 Go。我想用不同的命令行参数多次从 Go 调用一个封闭源代码的可执行文件,具有一点并发性。我生成的代码运行良好,但我想获得您的意见以改进它。由于我处于早期学习阶段,我还将解释我的工作流程。

为简单起见,这里假设这个“外部闭源程序”是zenity一个 Linux 命令行工具,可以从命令行显示图形消息框。

从 Go 调用可执行文件

所以,在 Go 中,我会这样:

这应该工作得很好。请注意,.Run()它的功能等同.Start().Wait(). 这很好,但如果我只想执行这个程序一次,整个编程的东西就不值得了。所以让我们多次这样做。

多次调用可执行文件

现在我有了这个工作,我想多次调用我的程序,使用自定义命令行参数(这里只是i为了简单起见)。

好的,我们做到了!但是我还是看不出 Go 相对于 Python 的优势……这段代码实际上是以串行方式执行的。我有一个多核 CPU,我想利用它。所以让我们用 goroutines 添加一些并发性。

Goroutines,或者一种使我的程序并行的方法

a)第一次尝试:只需在任何地方添加“go”

让我们重写我们的代码,使事情更容易调用和重用,并添加著名的go关键字:

没有什么!问题是什么?所有的 goroutines 都会立即执行。我真的不知道为什么没有执行zenity,但是AFAIK,Go程序在zenity外部程序甚至可以初始化之前就退出了。使用time.Sleep: 等待几秒钟就足以让 8 个 zenity 实例自行启动。我不知道这是否可以被认为是一个错误。

更糟糕的是,我实际上想要调用的真正程序需要一段时间才能执行。如果我在我的 4 核 CPU 上并行执行该程序的 8 个实例,会浪费一些时间进行大量上下文切换……我不知道普通 Go goroutine 的行为如何,但exec.Command 在 8 个不同的线程中启动 zenity 8 次. 更糟糕的是,我想执行这个程序超过 100,000 次。在 goroutines 中一次完成所有这些工作根本不会有效。不过,我想利用我的 4 核 CPU!

b) 第二次尝试:使用 goroutine 池

在线资源倾向于推荐sync.WaitGroup用于此类工作。这种方法的问题在于,您基本上是在处理一批 goroutine:如果我创建了 4 个成员的 WaitGroup,Go 程序将等待所有4 个外部程序完成,然后再调用新的一批 4 个程序。这效率不高:CPU 又一次被浪费了。

其他一些资源建议使用缓冲通道来完成这项工作:

这看起来很丑陋。频道不是为此目的而设计的:我正在利用副作用。我喜欢这个概念,defer但我讨厌必须声明一个函数(甚至是一个 lambda)才能从我创建的虚拟通道中弹出一个值。哦,当然,使用虚拟通道本身就是丑陋的。

c) 第三次尝试:当所有孩子都死了时死

现在我们快完成了。我只需要考虑另一个副作用:Go 程序在所有 zenity 弹出窗口关闭之前关闭。这是因为当循环结束时(第 8 次迭代),没有什么能阻止程序结束。这一次,sync.WaitGroup将是有用的。

完毕。

我的问题

  • 你知道任何其他适当的方法来限制一次执行的 goroutines 的数量吗?

我不是指线程;Go 内部如何管理 goroutine 无关紧要。我的意思是限制一次启动的 goroutine 的数量:exec.Command每次调用时都会创建一个新线程,所以我应该控制它被调用的次数。

  • 这段代码对你来说看起来不错吗?
  • 您知道在这种情况下如何避免使用虚拟通道吗?

我无法说服自己这样的虚拟通道是要走的路。

0 投票
2 回答
49587 浏览

concurrency - Golang并发:如何从不同的goroutine附加到同一个切片

我有并发的 goroutines 想要将一个(指向一个)结构​​的(指针)附加到同一个切片。你如何在 Go 中编写它以使其并发安全?

这将是我的并发不安全代码,使用等待组:

我想你需要使用 go 通道来保证并发安全。任何人都可以举个例子吗?

0 投票
1 回答
2081 浏览

concurrency - Go 如何决定何时在 goroutine 之间进行上下文切换?

我很好奇 Go 语言是如何调度 goroutines 的。它是仅在通道请求和 I/O 期间切换,还是有一个周期性的协程切换循环?

0 投票
3 回答
320 浏览

go - 第一个 goroutine 示例,奇怪的结果

这个例子取自tour.golang.org/#63

输出

为什么world只打印4times 而不是5?


编辑:可以从golang规范中引用答案:

程序执行首先初始化主包,然后调用函数 main。当 main 函数返回时,程序退出。它不会等待其他(非主)goroutine 完成。