sync.WaitGroup 的示例正确吗?

2024-04-26

这个例子的用法是sync.WaitGroup正确的?它给出了预期的结果,但我不确定wg.Add(4)和位置wg.Done()。一次添加四个 goroutine 是否有意义wg.Add()?

http://play.golang.org/p/ecvYHiie0P http://play.golang.org/p/ecvYHiie0P

package main

import (
    "fmt"
    "sync"
    "time"
)

func dosomething(millisecs time.Duration, wg *sync.WaitGroup) {
    duration := millisecs * time.Millisecond
    time.Sleep(duration)
    fmt.Println("Function in background, duration:", duration)
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(4)
    go dosomething(200, &wg)
    go dosomething(400, &wg)
    go dosomething(150, &wg)
    go dosomething(600, &wg)

    wg.Wait()
    fmt.Println("Done")
}

结果(如预期):

Function in background, duration: 150ms
Function in background, duration: 200ms
Function in background, duration: 400ms
Function in background, duration: 600ms
Done

是的,这个例子是正确的。重要的是wg.Add()发生在go声明以防止竞争条件。以下也将是正确的:

func main() {
    var wg sync.WaitGroup
    wg.Add(1)
    go dosomething(200, &wg)
    wg.Add(1)
    go dosomething(400, &wg)
    wg.Add(1)
    go dosomething(150, &wg)
    wg.Add(1)
    go dosomething(600, &wg)

    wg.Wait()
    fmt.Println("Done")
}

然而,打电话是毫无意义的wg.Add当你已经知道它会被调用多少次时,就会一遍又一遍地重复。


Waitgroups如果计数器降到零以下,就会出现恐慌。计数器从零开始,每次Done() is a -1和每个Add()取决于参数。因此,为了确保计数器永远不会低于并避免恐慌,您需要Add() to be 保证来之前Done().

在 Go 中,这样的保证是由记忆模型 http://golang.org/ref/mem.

内存模型指出,单个 goroutine 中的所有语句似乎都按照写入的顺序执行。它们实际上可能不会按这个顺序排列,但结果就像是这样。还保证了goroutine 直到之后才会运行go调用它的声明 http://golang.org/ref/mem#tmp_4。自从Add()发生在go声明和go语句发生在Done(),我们知道Add()发生在Done().

如果你有go声明出现在Add(),程序可以正确运行。然而,这将是一个竞争条件,因为它无法得到保证。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

sync.WaitGroup 的示例正确吗? 的相关文章

随机推荐

  • 未定义拖放区

    我对 JavaScript 还很陌生 这让我发疯 我想使用 Dropzone js 因此我从以下位置下载了文件 dropzone jshere https raw githubusercontent com enyo dropzone ma
  • 使用图像的java自定义形状框架[重复]

    这个问题在这里已经有答案了 我喜欢创建一个像这个图像一样的java jframe 我已经用不同的形状 如三角形 圆形 多边形和一些疯狂的形状 创建了jframe 但是问题是太难 99 不可能 创建像这个图像的形状 所以我怎样才能制作一个像这
  • 在我的 flutter 应用程序中单击容器时更改容器的颜色

    我通过 API 获取了一些兴趣 数据 并向他们展示了使用未来的构建器作为容器 我想在单击容器时更改容器的背景颜色 这是我所做的 当我单击一个容器时 它会更改所有容器的背景颜色 我在容器的颜色中添加了一个 if 条件来检查它是否被单击 颜色
  • 表达式类型不明确,没有更多上下文 swift 4.0

    我正在实施pod Socket IO Client Swift but in SocketEngine swift文件我收到此错误 private func handleBase64 message String binary in bas
  • Proguard 混淆不起作用

    我试图混淆我的包名称 包括我使用的库之一 我在我的 gradle 文件中使用这个构建配置 buildTypes debug versionNameSuffix Development debuggable true runProguard
  • 使用 openGL、SOIL 加载图像

    我尝试了很多使用 SOIL 在 openGL 中加载和显示图像的示例 运行下面的源代码时 它仅显示一个没有图像的白色四边形 我尝试打开一个名为 foto 的图像 我将图像文件放在程序的文件夹中 bool keyStates new bool
  • Delphi:设置 TByteDynArray 长度的问题

    问题已结束 答案已接受 替换为Delphi 7 访问冲突 TByteDynArray 问题 https stackoverflow com questions 3157732 delphi 7 access violation tbyted
  • 删除一个单词及其后面的所有内容

    假设我有一个字符串 C Program Files x86 Steam steam exe lets go 342131 some random text 我想从该字符串中删除 steam exe 以及之后的所有内容 所以我修剪过的字符串看
  • 如何使用 Square OKHTTP 固定证书?

    我想我需要创建一个新的 SSL 套接字工厂 另外 我不想使用全局 SSL 上下文 https github com square okhttp issues 184 https github com square okhttp issues
  • 从上三角初始化对称 Theano dmatrix

    我正在尝试拟合一个部分由对称矩阵参数化的 Theano 模型A 为了加强对称性A 我希望能够构建A通过仅传入上三角形中的值 等效的 numpy 代码可能如下所示 import numpy as np def make symmetric p
  • 当我尝试安装 Angular 时权限被拒绝

    Error EACCES permission denied access Users gs npm global lib node modules angular cli npm ERR errno 13 npm ERR code EAC
  • 卸载现有版本的 apk(如果存在),然后重新安装

    我在使用模拟器时遇到即时运行问题 我按照目录删除它 slice 8 但它仍然是相同的错误消息 我有什么想法可以解决它吗 禁用 取消选中 即时运行settings gt build execution deployment gt Instan
  • iOS DeviceCheck API -GenerateToken 给出错误代码 0

    我正在尝试实现新的 iOS 11 DeviceCheck API https developer apple com documentation devicecheck https developer apple com documenta
  • 在 Mac OS X 中创建虚拟 USB 设备

    我尝试以编程方式在 Mac OS 中添加带有驱动程序的虚拟 USB 设备 IOKit 文档说 传统上 虚拟设备的驱动程序在 IOResources 上匹配 因为虚拟设备不发布自己的 nub 此类驱动程序的另一个示例是 HelloIOKit
  • R 中另一个变量的滚动总和

    我想通过 ID 获取 7 天的滚动总和 假设我的数据如下所示 data lt as data frame matrix NA 42 3 data V1 lt seq as Date 2014 05 01 as Date 2014 09 01
  • CakePHP 3.0:如何在重复键更新时进行插入?

    我有一个数组 articles像这样 int 0 gt id gt 940039 xe dsca gt P2768G 1 xe citg gt 1F0200 xe cuni gt stk xe seak gt P2768G 1 xe sea
  • 使用 Node js 和 Express 提供 pdf 文件

    所有的PDF文件都保存在服务器的文件系统中 如何使文件可以在客户端下载 对于前 app use pdfDownload function req res var pathToTheFile req body fileName readFil
  • 使用 YUIcompressor 压缩多个 JavaScript 文件?

    我正在尝试使用 YUI 压缩机压缩多个 JS 文件 我认为我的语法错误 我想压缩目录中以以下内容开头的所有文件at 然而 当 YUI 压缩机运行时 我发现 YUI 压缩机在输出中只放置了一个文件的压缩版本 具体来说 假设我有三个文件 at
  • UIButton 在 iOS 7 中无法正常工作

    我有一个 UIButton 问题 它在 iOS6 中工作得很好 但在 iOS7 中无法响应触摸事件 为了澄清 请参见下图 失败的按钮是 UIView 中的 Discard All 按钮 请注意 此按钮只是暂时禁用 这不是问题 我只是没有启用
  • sync.WaitGroup 的示例正确吗?

    这个例子的用法是sync WaitGroup正确的 它给出了预期的结果 但我不确定wg Add 4 和位置wg Done 一次添加四个 goroutine 是否有意义wg Add http play golang org p ecvYHii