- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
var wg sync.WaitGroup
var v int32 = 0
for i = 0; i < 100; i++{
go func(){
wg.Add(1) // wrong place
atomic.AddInt32(&v,1)
wg.Done()
}
}
wg.Wait()
fmt.Println(v)
这是我从这个视频中看到的一段代码 https://subscription.packtpub.com/video/application_development/9781788994880/97598/97608/goroutines
但是 v
总是小于 100
,我认为原因可能是 wg.Wait()
会比预期提前结束因为我们将 wg.Add(1)
放在匿名函数中,并且在同一个 goroutine 中 wg.Done()
将立即被调用,因此主 goroutine 从阻塞状态恢复执行.
但是如果我们将 wg.Add(1)
放入 for 循环中,v 将始终为 100
。
var wg sync.WaitGroup
var v int32 = 0
for i = 0; i < 100; i++{
wg.Add(1)
go func(){
atomic.AddInt32(&v,1)
wg.Done()
}
}
wg.Wait()
fmt.Println(v)
我的问题是为什么我们可以保证 main goroutine 总是阻塞在这里使得 v 最终等于 100。如果在 for 循环之前向 wg
添加一个任务,并且主 goroutine 在这里恢复执行是否可能,因为此时没有任务。
最佳答案
在启动将调用 wg.Done()
的 goroutine 之前,您应该始终调用 wg.Add()
。
在您更正的示例中,main
goroutine 只能在 for
循环之后到达 wg.Wait()
,这保证您调用 wg.Add()
一百次,所以 wg.Wait()
将阻塞,直到 wg.Done()
被调用 100
次。
当 wg.Add()
调用在新的 goroutine 中时,不能保证任何 wg.Add()
调用都会在 main
goroutine 到达 wg.Wait()
因为它们同时运行(直到此时没有同步)。这种情况下的行为是不确定的(取决于 goroutine 调度程序,它在没有显式同步的情况下是不确定的)。
请注意,如果您知道循环执行 100
次迭代,另一种方法是在循环之前调用 wg.Add(100)
。不过,我建议不要这样做,因为当循环包含 break
或 continue
操作时需要小心,这可能会导致启动的 goroutine 较少,从而最终导致你的 main
goroutine 卡住了。是的,在你的情况下这可能是微不足道的,但如果这段代码及时发展,它可能会变得不那么明显,并可能导致 future 的错误。当场景中涉及启动 goroutines 时,说它更快是无关紧要的。如果您只在启动 goroutine 之前调用 wg.Add(1)
,那么稍后您有条件地跳过这部分也没关系,因为您将跳过 wg.Add()
同时启动 goroutine,您的代码将保持正确。
使用 sync.WaitGroup
时要遵循的简单“规则” :(引自 this answer)
WaitGroup.Add()
在 go
之前的“原始”goroutine(开始一个新的)中声明WaitGroup.Done()
deferred,所以即使 goroutine panic 也会被调用WaitGroup
传递给其他函数(而不是使用包级变量),你必须传递一个指向它的指针,否则 WaitGroup
(这是a struct) 将被复制,并且在副本上调用的 Done()
方法不会在原始关于go - wg.Add() 放在哪里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65213707/
var wg sync.WaitGroup var v int32 = 0 for i = 0; i < 100; i++{ go func(){ wg.Add(1) // wro
1。我触发了一个 goroutine(运行第三方程序),我正在使用 wg.Wait() 等待它完成 2。在 wg.Wait() 之前,我想为用户提供一个选项来取消正在运行的第三方程序(如果他愿意的话)
假设我有一个函数 IsAPrimaryColour(),它通过调用其他三个函数 IsRed()、IsGreen() 和 来工作>IsBlue()。由于这三个功能彼此相当独立,因此它们可以同时运行。返回
假设我有一个函数 IsAPrimaryColour(),它通过调用其他三个函数 IsRed()、IsGreen() 和 来工作>IsBlue()。由于这三个功能彼此相当独立,因此它们可以同时运行。返回
我在使用 defer wg.Done 和 channel 时遇到问题。 如果我像下面这样编码,就没有问题。 for i := 0; i < ntasks; i++ { wg.Add(1)
我有一个要抓取的网址列表。我想做的是将所有成功抓取的页面数据存储到一个 channel 中,当我完成后,将其转储到一个 slice 中。我不知道我会得到多少成功的抓取,所以我不能指定一个固定的长度。我
我正在使用 PIC-IoT WG wifi 开发板开展一个项目。我正在尝试修改演示代码以便能够在我自己的服务器上使用它。该演示在多个地方使用了这样的代码: #include static void
我有一个示例代码(您可以在 Go Playground 上找到它): package main import ( "fmt" "sync" "time" ) func main
关闭。 这个问题不符合 Stack Overflow guidelines 。它目前不接受答案。 这个问题似乎与 a specific programming problem, a software
所有在 Debian 9+ 上运行都没有问题,使用相同的设置和安装方法。 当我尝试启动服务时 systemctl start wg-quick@wg0 它在日志中显示错误: wg-quick[9290
我目前正在开发一个用 java 实现的已安装桌面应用程序。我打算将 Google Calendar API 集成到应用程序中。 在授权过程中,我来到了这个阶段,我只能通过触发显示用户同意页面的浏览器来
我是一名优秀的程序员,十分优秀!