go语言WaitGroup中使用协程嵌套示例代码
WaitGroup是一个计数信号量,可以用来记录并维护运行的goroutine,
它是用来阻塞主协程,可以等待所有协程执行完。
示例代码:
WaitGroup里面在嵌套WaitGroup
func TestGoRoutine(t *testing.T) {
wg := sync.WaitGroup{}
limitNum := 3
wg.Add(limitNum)
for j := 0; j < limitNum; j++ {
go func(index int) {
defer wg.Done()
testRoutine(index)
}(j)
}
wg.Wait()
}
func testRoutine(index int) {
wg2 := sync.WaitGroup{}
limitNum2 := 3
wg2.Add(limitNum2)
for i := 0; i < limitNum2; i++ {
go func(index2 int) {
defer wg2.Done()
fmt.Printf("测试上级Index[%d]Index2:[%d] \n", index, index2)
}(i)
}
wg2.Wait()
}
打印测试结果:
测试上级Index[2]Index2:[2]
测试上级Index[2]Index2:[1]
测试上级Index[1]Index2:[2]
测试上级Index[1]Index2:[0]
测试上级Index[1]Index2:[1]
测试上级Index[2]Index2:[0]
测试上级Index[0]Index2:[1]
测试上级Index[0]Index2:[2]
测试上级Index[0]Index2:[0]
--- PASS: TestGoRoutine (0.00s)
PASS
进程完成,并显示退出代码 0
相关知识
go协程是平行的,是忽略上下级关系的
原理:
1.waitgroup结构体中state1的格式很重要。共占12个字节。因为64位原子操作需要64位对齐,但32位编译器无法确保它。
所以分配12个字节,然后使用其中的对齐8个字节作为状态数,另外4个作为存储sema;
2.调用Add时,操作高位的计数器值进行加减;
3.调用wait时,低32位的wait数会累加,如果获取到释放的信号后且计数器是0,则调用原语递减信号量的值 结束阻塞。
相关文章