Go WaitGroup及Cond底层实现原理

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日

相关文章

  • SpringBoot自定义转换器应用实例讲解

    SpringBoot自定义转换器应用实例讲解 在SpringBoot中,通过自定义转换器可以实现将一个类型转换为另外一个类型。本文将详细介绍如何在SpringBoot应用中创建自定义转换器,并提供两个示例。 创建自定义转换器 步骤如下: 创建一个类并实现org.springframework.core.convert.converter.Converter接…

    other 2023年6月25日
    00
  • python 内置错误类型 Built-in Exceptions

    Python 内置错误类型 Built-in Exceptions 在 Python 中,错误类型被定义为异常。每个异常都是一个类,这些类都是内置到 Python 中的。在程序执行过程中,当 Python 遇到错误时会自动抛出相应的异常。 以下是 Python 内置的一些常见异常及其描述: 1. Exception(所有异常的基类) 在 Python 中,所…

    其他 2023年3月28日
    00
  • vue安装less-loader依赖失败问题及解决方案

    首先需要了解的是,less-loader是一个用于解析less文件的webpack加载器。在使用Vue框架开发时,我们常常需要使用到less进行样式定义,所以需要安装less-loader依赖。但在安装less-loader依赖时,可能会遇到安装失败的问题。下面是解决方案的完整攻略: 问题描述 在使用npm或yarn安装Vue项目所需的less-loader…

    other 2023年6月26日
    00
  • nginx解决400badrequest的方法

    以下是Nginx解决400 Bad Request的完整攻略,包括两个示例说明。 步骤 以下是Nginx解决400 Bad Request的基本步骤: 打开Nginx配置文件。 使用文本编辑器打开Nginx的配置文件,通常位于/etc/nginx/nginx.conf。 sudo nano /etc/nginx/nginx.conf 查找http段。 在配置…

    other 2023年5月6日
    00
  • s3clientaws

    以下是关于“s3clientaws”的完整攻略: 什么是s3clientaws s3clientaws是一个用于访问Amazon S3服务的AWS SDK for JavaScript的客户端。它提供了一组API,可以让开发者在中方便地访问Amazon S3服务,包括上传、下载、删除、复制等操作。 s3clientaws的安装和配置 可以通过npm安装s3c…

    other 2023年5月7日
    00
  • Java for循环的几种用法分析

    Java for循环的几种用法分析 在Java中,for循环是一种常用的循环结构,用于重复执行一段代码。它提供了多种用法,可以根据不同的需求选择适合的方式。下面将详细介绍Java for循环的几种用法,并提供示例说明。 1. 基本的for循环 基本的for循环是最常见的形式,它由三个部分组成:初始化、条件判断和迭代操作。循环会在每次迭代时检查条件,只有条件为…

    other 2023年8月15日
    00
  • RealProxy深入

    RealProxy深入的完整攻略 RealProxy是.NET Framework中的一个类,用于创建动态代理。动态代理是一种在运行时创建代理对象的技术,可以用于实现AOP(面向切面编程)等功能。在.NET Framework中,可以使用RealProxy类创建动态代理对象。 RealProxy的使用方法 使用RealProxy创建动态代理对象的步骤如下: …

    other 2023年5月5日
    00
  • 详解javascript中offsetleft属性的用法(转)

    详解javascript中offsetLeft属性的用法(转) 在前端开发中,我们经常需要获取页面元素在文档流中的位置信息。其中,offsetLeft属性可用于获取某个 HTML 元素相对与其父元素的左侧偏移量(即元素左边缘与其父元素左边缘之间的距离),并且不考虑边框宽度。本文将详解javascript中offsetLeft属性的用法,为大家讲解如何正确地使…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部