问题标签 [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 投票
1 回答
177 浏览

concurrency - 导致严重减速和头痛的 goroutines

我在使用 goroutines 时遇到了一些问题。为什么这段代码在 ~125ms 内执行(注意顺序执行):

当这段代码大约需要 20 秒时(使用 goroutine 并发执行):

在 i7 720QM (4C/8T) 8GB RAM linux/x86-64 上使用 go 1.0.3 也使用 1.0.2 构建和测试,在同一台机器上遇到了同样的问题。

编辑:由下面的@jnml 解决。如果有人关心这里的新固定并发代码,那就是:

0 投票
1 回答
9019 浏览

go - 是否有一些优雅的方式来暂停和恢复任何其他 goroutine?

就我而言,我有数千个 goroutines 同时作为work(). 我也有一个sync()goroutine。启动时sync,我需要任何其他 goroutine 在同步作业完成后暂停一段时间。这是我的代码:

现在的问题是,由于<-读取时总是阻塞,所以每次去sync_stat := <- channel都是阻塞的。我知道如果频道关闭它不会被阻止,但是由于我必须使用这个频道直到work()退出,我没有找到任何方法来重新打开一个关闭的频道。

我怀疑自己走错路了,因此感谢您提供任何帮助。是否有一些“优雅”的方式来暂停和恢复任何其他 goroutine?

0 投票
2 回答
1402 浏览

go - goroutines 是如何工作的,当主进程完成时它们会死吗?

我编写了一个简单的小示例,将 1000 万条记录插入 mongodb。我首先让它按顺序工作。然后我查找了如何进行并发,并找到了 goroutines。这似乎是我想要的,但它的行为并不像我预期的那样。我实现了一个 WaitGroup 来阻止程序在所有 goroutine 完成之前退出,但我仍然遇到问题。

所以我将从正在发生的事情开始,然后显示代码。当我在没有 goroutine 的情况下运行代码时,所有 1000 万条记录都可以插入到 mongodb 中。但是,当我添加 goroutine 时,会输入一些不确定的数量.. 通常大约 8500 给或取几百。我检查了 mongodb 日志以查看它是否有问题并且没有任何显示。所以我不确定是不是这样,可能是,只是没有被记录。无论如何,这是代码:

(旁注:我一次只做 1 条记录,但我已经把它分成了一个方法,所以我可以在将来一次测试多条记录。只是还没弄清楚如何用 mongodb然而。)

0 投票
2 回答
9806 浏览

go - 在 goroutines 中启动 goroutines 是否可以接受?

我现在正在学习 Go,我的第一个项目是一个简单的 ping 脚本。本质上,我想 ping 一堆 url,并在每个响应时等待 XXX 秒,然后再次 ping。这是删减的代码:

在我的 Get 请求中,我之前调用了 defer res.Body.Close() ,但在应用程序运行了一段时间后,这令人恐慌。我假设在 goroutine 被垃圾收集并且 res 不再存在之前,defer 无法在响应上调用 Close()。

这让我想到如果在 goroutine 内部调用 goroutine 是最佳实践,或者我是否导致函数永远不会退出,那么只有在 goroutine 被垃圾收集后才会调用 defer。

0 投票
2 回答
776 浏览

synchronization - 阻塞通道发送错误的同步范例以及原因

Effective Go给出了这个示例,说明如何使用通道模拟信号量:

它还说:因为数据同步发生在来自通道的接收上(即,发送“发生在”接收之前;请参阅Go Memory 模型),信号量的获取必须在通道接收上,而不是发送上。

现在,我想我理解了 Go 内存模型和“发生在之前”的定义。但是我看不到阻塞通道发送有什么问题:

此代码(上面有semServe不变)以相反的方式使用缓冲通道。频道开始为空。在进入handle时,如果已经有MaxOutstandinggoroutines 正在执行该过程,则发送将阻塞。一旦其中一个完成处理并从通道中“释放”一个插槽,通过接收一个 int,我们的发送将被解除阻塞,goroutine 将开始自己的处理。

正如教科书似乎暗示的那样,为什么这是一种不好的同步方式?

释放通道槽的接收操作是否不会“发生在”将使用同一槽的发送之前?这怎么可能?


换句话说,语言参考“缓冲通道上的发送[阻塞直到]缓冲区中有空间。”

但是内存模型只说“来自无缓冲通道的接收发生在该通道上的发送完成之前”。特别是,它并没有说从已满的缓冲通道接收发生在该通道上的发送完成之前。

这是一些不能相信做正确事情的极端案例吗?(这实际上是将被阻止的发送与解除阻止的接收同步)

如果是这样的话,它看起来像是一种令人讨厌的竞争条件,这种语言旨在最大限度地减少偷偷摸摸的竞争条件:-(

0 投票
3 回答
13251 浏览

concurrency - 等待 n 个 goroutine 终止

我需要启动大量的 goroutine 并等待它们的终止。直观的方法似乎是使用一个通道来等到所有这些都完成:

但问题是对象的数量以及 goroutine 的数量可能会发生变化。是否可以更改通道的缓冲区大小?

有没有更优雅的方法来做到这一点?

0 投票
2 回答
2032 浏览

memory-leaks - Will the garbage collector collect Go routines that will never continue?

Consider the following code as a simplified example:

The function provide creates a go routine printer that prints the data provide generates.

My question is, what happens after provide returns and printer starts blocking on the empty channel. Will the go routine leak, as there is no further reference to c or will the garbage collector catch this case and dispose both the go routine and c?

If it is indeed the case that this kind of code causes a memory leak, what strategies can I do to prevent such a memory leak from happening?

0 投票
2 回答
98 浏览

parallel-processing - go函数通道死锁

即使我只是通过一个并从通道获得一个输出,为什么还会出现死锁?

0 投票
1 回答
1165 浏览

go - 为什么带有网络 i/o 的 goroutine 会被阻塞?

我在 Ubuntu 13.04 上使用 go 1.1 devel

根据http://golang.org/doc/faq#goroutines

当协程阻塞时,例如通过调用阻塞系统调用,运行时会自动将同一操作系统线程上的其他协程移动到不同的可运行线程,这样它们就不会被阻塞。

我正在尝试编写一个下载器,它可以使用 goroutine 分块下载一个大文件,这是我想出的最好的 goroutine:

完整的脚本可在https://github.com/tuxcanfly/godown/blob/master/godown.go获得

即使文件正在正确下载和保存,我可以看到第二个块仅在第一个块完成时才开始。

分块下载不应该并行运行,还是我做错了什么?

0 投票
1 回答
622 浏览

go - 如何正确使用标准库或第三方中的 Golang 包与 Goroutines?

嗨 Golang 程序员,

首先,如果我的问题最初不是很清楚,我深表歉意,但是在编写使用标准库或其他库时使用 Goroutines 的 Golang 代码时,我试图了解正确的使用模式。

让我详细说明一下:假设我导入了一些我没有亲笔书写但想要使用的包。假设这个包以某种方式向 Flickr 等网站发出简单的 http get 请求。如果我想要一个并发请求,我可以在函数调用前加上 go 关键字。但是我怎么知道,这个包在执行请求时并没有自己做一些内部 go 调用,因此使我的 go 调用变得多余?

Golang 包通常在文档中说他们的方法是“绿色的”吗?或者他们提供了两种版本的方法,一种是绿色的,一种是直接同步的?

在我寻求理解 Go 习惯用法和使用模式的过程中,我什至在使用标准库中的包时感觉我无法确定我的 go 命令是否是必要的。我想我可以分析调用,或者编写测试代码,但是必须弄清楚一个函数是否已经“绿色”,这感觉很奇怪。

我想另一种可能性是由我来研究我正在使用的任何东西的源代码并了解它应该如何使用以及是否需要 go 关键字。

如果有人能对此有所了解或指出正确的文档甚至是 Golang 的截屏视频,我将不胜感激。我认为 Rob Pike 在一次演讲中简要提到过,一个好的客户端 api 编写的 go 只是以典型的同步方式编写的,由该 api 的调用者来选择是否将其设为绿色。

谢谢你的时间,

-拉尔夫