Go WaitGroup及Cond底层实现原理

yizhihongxing

Go WaitGroup及Cond底层实现原理

WaitGroup

WaitGroup是Golang提供的一个线程同步的工具,它可以使一个线程等待一组线程的完成操作。

实现原理

WaitGroup内部有一个计数器,初始值为0。每次调用Add方法,计数器就加1;每次调用Done方法,计数器就减1;每次调用Wait方法,它会阻塞等待计数器的值为0。

var wg sync.WaitGroup

func main() {
    for i := 0; i < 10; i++ {
        wg.Add(1)   // 计数器加1
        go func(wg *sync.WaitGroup) {
            defer wg.Done() // 计数器减1
            fmt.Println("Hello, World!")
        }(&wg)
    }
    wg.Wait()   // 等待计数器为0
}

示例

一个等待多个goroutine完成的例子:

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    wg.Add(2)

    go func(wg *sync.WaitGroup) {
        defer wg.Done()
        fmt.Println("Routine 1")
    }(wg)

    go func(wg *sync.WaitGroup) {
        defer wg.Done()
        fmt.Println("Routine 2")
    }(wg)

    wg.Wait()
    fmt.Println("All routines are done!")
}

Cond

Cond是条件变量,是Go语言中一个比较底层的同步原语。它的作用是在多个goroutine之间协调调度执行。

实现原理

Cond是结合Mutex(锁)来使用的。开发人员可以使用Cond来等待或者触发某个事件的发生。当一个goroutine等待一个事件发生时,它会阻塞自己并释放Mutex锁,供其他的goroutine使用。当事件发生时,其他的goroutine可以通知正在等待的goroutine,使得它重新开始执行。

type Cond struct {
    noCopy noCopy

    L Locker // 互斥锁
    notify  notifyList
    checker copyChecker  // 用来检查复制
}

Cond类型内部包含一个互斥锁,一个通知列表(notifyList)和一个复制检查器(copyChecker)。

示例

下面是一个生产者/消费者模型的示例:

package main

import (
    "fmt"
    "sync"
)

var buffer []int
var bufferLock sync.Mutex
var bufferCond = sync.NewCond(&bufferLock)
var done = make(chan bool)

func producer() {
    for i := 0; i < 10; i++ {
        bufferLock.Lock()
        buffer = append(buffer, i)
        fmt.Println("Producing...", i)
        bufferLock.Unlock()

        bufferCond.Signal() // 唤醒一个消费者
    }
    done <- true
}

func consumer(id int) {
    for {
        bufferLock.Lock()
        for len(buffer) == 0 {
            bufferCond.Wait() // 挂起等待直到收到生产者的信号
        }
        value := buffer[0]
        buffer = buffer[1:]
        fmt.Printf("Consumer %d consuming %d\n", id, value)
        bufferLock.Unlock()
    }
}

func main() {
    for i := 0; i < 3; i++ {
        go consumer(i)
    }

    go producer()

    <-done
    fmt.Println("Done!")
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Go WaitGroup及Cond底层实现原理 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • java实现中缀表达式转后缀的方法

    Java实现中缀表达式转后缀的方法 中缀表达式是我们常见的数学表达式形式,例如2 + 3 * 4。而后缀表达式(也称为逆波兰表达式)是一种将操作符放在操作数之后的表达式形式,例如2 3 4 * +。在计算机科学中,我们通常将中缀表达式转换为后缀表达式,以便更容易进行计算。 下面是一种使用Java实现中缀表达式转后缀表达式的方法: 步骤1:创建一个空的栈和一个…

    other 2023年8月6日
    00
  • Fiddler抓包6-get请求(url详解)

    下面是“Fiddler抓包6-get请求(url详解)”的完整攻略,包括Fiddler的安装、抓包设置、抓包过程和两个示例等方面。 Fiddler的安装 首先,需要下载并安装Fiddler。可以使用以下步骤下载并安装Fiddler: 打开Fiddler官网; 下载Fiddler安装包; 运行安装包; 按照安装向导的提示完成安装。 安装完成后,可以开始设置Fi…

    other 2023年5月6日
    00
  • Android 完全退出应用程序的解决方法

    Android 完全退出应用程序的解决方法 在Android应用程序中,用户通常可以通过点击手机的返回键或者是HOME键来跳出应用程序,但这并不代表该应用程序已经完全退出。这时,该应用程序可能仍在后台运行,需要进一步的处理才能退出完全。下面将介绍两种常见的方法来实现Android应用程序的完全退出。 方法一:使用系统API退出程序 Android系统提供了相…

    other 2023年6月25日
    00
  • dos批处理文件中的变量小结

    DOS批处理文件中的变量小结攻略 DOS批处理文件中的变量是一种用于存储和操作数据的特殊类型。在本攻略中,我们将详细讲解如何在DOS批处理文件中使用变量,并提供两个示例说明。 1. 定义变量 在DOS批处理文件中,可以使用set命令来定义变量。变量名通常以%符号包围,例如%variable%。以下是定义变量的示例: @echo off set variabl…

    other 2023年8月9日
    00
  • Python配置文件解析模块ConfigParser使用实例

    Python中内置了一个标准模块ConfigParser,该模块可以帮助开发者读取和解析常见的配置文件,如INI格式的文件。本文将详细讲解如何使用该模块来读取和解析INI文件。 安装ConfigParser ConfigParser是Python标准库中自带的模块,因此无需额外安装。 快速入门 首先,需要引入ConfigParser库: import con…

    other 2023年6月25日
    00
  • SpringBoot整合WebService的实现示例

    针对“SpringBoot整合WebService的实现示例”,我们可以按照以下步骤进行整合。 1. 添加依赖 在项目的pom.xml文件中添加以下依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-bo…

    other 2023年6月27日
    00
  • JavaScript常见继承模式实例小结

    下面是JavaScript常见继承模式实例小结的完整攻略。 常见继承模式实例小结 在JavaScript中实现继承有多种方法,下面将会介绍常见的几种方法,并通过示例说明。 1. 原型链继承 原型链继承是JavaScript中最常见的继承模式,它的实现方法如下: function Animal (name) { this.name = name } Anima…

    other 2023年6月27日
    00
  • 详解Webpack抽离第三方类库以及common解决方案

    Webpack是前端工程化中不可避免的一环,它可以将我们项目中的各种资源进行打包和压缩,使得项目的性能得到有效优化。其中webpack从v4开始,废弃了CommonsChunkPlugin插件,提供了新的功能:SplitChunksPlugin。它可以帮助我们更好的抽离第三方类库以及项目中常用模块。下面我们来详细讲解如何进行配置。 抽离第三方类库 Webpa…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部