golang语言异步通信之WaitGroup

2024-05-14 02:48

本文主要是介绍golang语言异步通信之WaitGroup,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

golang语言异步通信之WaitGroup

96 CodingCode 关注

2018.02.07 14:57 字数 267 阅读 88评论 0喜欢 0

golang语言异步通信之WaitGroup

简介

WaitGroup的用途是使得主线程一直阻塞等待直到所有相关的子goroutine都已经完成了任务。

sync.WaitGroup只有3个API

  1. Add() # 添加计数
  2. Done() # 减掉计数,等价于Add(-1),这样sync.WaitGroup只有两个API了
  3. Wait() # 阻塞直到计数为零

用法例子1:正常用法


var wg sync.WaitGroupfunc foo1() {log.Println("entry foo1")time.Sleep(5 * time.Second)wg.Done()log.Println("exit foo1")
}func foo2() {log.Println("entry foo2")time.Sleep(2 * time.Second)wg.Done()log.Println("exit foo2")
}func main() {log.Println("entry main")wg.Add(1)go foo1()wg.Add(1)go foo2()log.Println("wg.Wait()")wg.Wait()log.Println("exit main")
}

主线程调用起两个子线程foo1和foo2并且等待他们的完成。
运行结果

2018/02/07 14:29:21 entry main
2018/02/07 14:29:21 wg.Wait()
2018/02/07 14:29:21 entry foo1
2018/02/07 14:29:21 entry foo2
2018/02/07 14:29:23 exit foo2
2018/02/07 14:29:26 exit foo1
2018/02/07 14:29:26 exit main

用法例子2:Done()过多

func main() {log.Println("entry main")var wg sync.WaitGroupwg.Done()log.Println("exit main")
}

在这个例子中,我们一上来就Done

$ go build && ./main
2018/02/07 14:33:59 entry main
panic: sync: negative WaitGroup countergoroutine 1 [running]:
sync.(*WaitGroup).Add(0xc42006c060, 0xffffffffffffffff)/usr/local/go/src/sync/waitgroup.go:75 +0x134
sync.(*WaitGroup).Done(0xc42006c060)/usr/local/go/src/sync/waitgroup.go:100 +0x34
main.main()/path_to/main.go:30 +0x89

计数器小于零,panic

用法例子3:Done()过少

var wg sync.WaitGroupfunc foo1() {log.Println("entry foo1")time.Sleep(5 * time.Second)//wg.Done()log.Println("exit foo1")
}func foo2() {log.Println("entry foo2")time.Sleep(2 * time.Second)//wg.Done()log.Println("exit foo2")
}func main() {log.Println("entry main")wg.Add(1)go foo1()wg.Add(1)go foo2()log.Println("wg.Wait()")wg.Wait()log.Println("exit main")
}

这个例子中我们注释掉了两个子线程中的Done()函数,运行结果:

$ go build && ./wg 
2018/02/07 14:36:03 entry main
2018/02/07 14:36:03 wg.Wait()
2018/02/07 14:36:03 entry foo2
2018/02/07 14:36:03 entry foo1
2018/02/07 14:36:05 exit foo2
2018/02/07 14:36:08 exit foo1
fatal error: all goroutines are asleep - deadlock!goroutine 1 [semacquire]:
sync.runtime_Semacquire(0x55ad7c)/usr/local/go/src/runtime/sema.go:56 +0x39
sync.(*WaitGroup).Wait(0x55ad70)/usr/local/go/src/sync/waitgroup.go:131 +0x72
main.main()/path_to/main.go:36 +0x127

这个错误表明,在最后一个活动线程foo1退出的时候,go检测到当前没有还在运行的线程,而还有在等待的线程,所以必然发生了死锁现象,这是go的一种自我保护机制。

这篇关于golang语言异步通信之WaitGroup的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/987537

相关文章

Go语言使用slices包轻松实现排序功能

《Go语言使用slices包轻松实现排序功能》在Go语言开发中,对数据进行排序是常见的需求,Go1.18版本引入的slices包提供了简洁高效的排序解决方案,支持内置类型和用户自定义类型的排序操作,本... 目录一、内置类型排序:字符串与整数的应用1. 字符串切片排序2. 整数切片排序二、检查切片排序状态:

基于C#实现MQTT通信实战

《基于C#实现MQTT通信实战》MQTT消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点,下面我们就来看看C#实现... 目录1、连接主机2、订阅消息3、发布消息MQTT(Message Queueing Telemetr

基于Go语言实现Base62编码的三种方式以及对比分析

《基于Go语言实现Base62编码的三种方式以及对比分析》Base62编码是一种在字符编码中使用62个字符的编码方式,在计算机科学中,,Go语言是一种静态类型、编译型语言,它由Google开发并开源,... 目录一、标准库现状与解决方案1. 标准库对比表2. 解决方案完整实现代码(含边界处理)二、关键实现细

如何合理管控Java语言的异常

《如何合理管控Java语言的异常》:本文主要介绍如何合理管控Java语言的异常问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、Thorwable类3、Error4、Exception类4.1、检查异常4.2、运行时异常5、处理方式5.1. 捕获异常

C语言中的常见进制转换详解(从二进制到十六进制)

《C语言中的常见进制转换详解(从二进制到十六进制)》进制转换是计算机编程中的一个常见任务,特别是在处理低级别的数据操作时,C语言作为一门底层编程语言,在进制转换方面提供了灵活的操作方式,今天,我们将深... 目录1、进制基础2、C语言中的进制转换2.1 从十进制转换为其他进制十进制转二进制十进制转八进制十进

$在R语言中的作用示例小结

《$在R语言中的作用示例小结》在R语言中,$是一个非常重要的操作符,主要用于访问对象的成员或组件,它的用途非常广泛,不仅限于数据框(dataframe),还可以用于列表(list)、环境(enviro... 目录1. 访问数据框(data frame)中的列2. 访问列表(list)中的元素3. 访问jav

Python 异步编程 asyncio简介及基本用法

《Python异步编程asyncio简介及基本用法》asyncio是Python的一个库,用于编写并发代码,使用协程、任务和Futures来处理I/O密集型和高延迟操作,本文给大家介绍Python... 目录1、asyncio是什么IO密集型任务特征2、怎么用1、基本用法2、关键字 async1、async

嵌入式Linux驱动中的异步通知机制详解

《嵌入式Linux驱动中的异步通知机制详解》:本文主要介绍嵌入式Linux驱动中的异步通知机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、异步通知的核心概念1. 什么是异步通知2. 异步通知的关键组件二、异步通知的实现原理三、代码示例分析1. 设备结构

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合