go语言sync.WaitGroup

一句话总结:sync.WaitGroup用于等待一个系列执行完成,不能保证数据的原子性操作。

go语言中有两种同步机制,一种是channel,另一种是锁机制。sync.WaitGroup是一种比较简单的同步机制,接口简洁只有三个,Add(),Done(),Wait();其中Add()是添加计数,Done()是减去一个计数,本质是Add(-1),Wait是阻塞等待计数为0;

// Done decrements the WaitGroup counter.
func (wg *WaitGroup) Done() {
	wg.Add(-1)
}


看一个没有同步的例子,很明显计数最后没有达到10

package main
 
import (
	"fmt"
	_ "sync"
	_ "time"
)
 
var g_cnt int = 0
 
func main() {
	for i := 0; i < 10; i++ {
		go func(i int) {
			g_cnt++
			fmt.Println("i:", i)
		}(i)
	}
	fmt.Println("g_cnt:", g_cnt)
}

结果:

g_cnt: 2

i: 0

i: 5

i: 2

i: 1

成功: 进程退出代码 0.


很明显主进程退出,goroutine没有全部执行完成就终止了。


package main
 
import (
	"fmt"
	_ "sync"
	"time"
)
 
var g_cnt int = 0
 
func main() {
	for i := 0; i < 1000; i++ {
		go func(i int) {
			g_cnt++
			fmt.Println("i:", i)
		}(i)
	}
	time.Sleep(10 * time.Second)
	fmt.Println("g_cnt:", g_cnt)
}

结果:

...........

i: 994

i: 989

i: 990

i: 995

i: 991

i: 999

i: 997

i: 985

i: 947

i: 998

g_cnt: 990

成功: 进程退出代码 0.


加了10s延时后所有goroutine都运行结束,由于没有同步机制,最后基数没有到达1000.


package main
 
import (
	"fmt"
	"sync"
	_ "time"
)
 
var g_cnt int = 0
 
func main() {
	var wg sync.WaitGroup
	for i := 0; i < 1000; i++ {
		go func(i int) {
			wg.Add(1)
			defer wg.Done()
			g_cnt++
			fmt.Println("i:", i)
		}(i)
	}
	wg.Wait()
	

结果:

.........

i: 977

i: 991

i: 983

i: 996

i: 992

i: 984

i: 993

i: 997

i: 982

i: 998

g_cnt: 996

成功: 进程退出代码 0.


可以看出,waitgroup只是保证了所有goroutine执行结束,从字面上看WaitGroup就是指等待一组,等待一个系列执行完成后才会继续向下执行。所有不能保证数据的原子性操作。

package main
 
import (
	"fmt"
	"sync"
	_ "time"
)
 
var g_cnt int = 0
 
func main() {
	var wg sync.WaitGroup
	var mutex sync.RWMutex
	for i := 0; i < 1000; i++ {
		go func(i int) {
			wg.Add(1)
			defer wg.Done()
			mutex.Lock()
			defer mutex.Unlock()
			g_cnt++
			fmt.Println("i:", i)
		}(i)
	}
	wg.Wait()
	fmt.Println("g_cnt:", g_cnt)
}

结果:

......

: 988

i: 995

i: 540

i: 996

i: 990

i: 997

i: 991

g_cnt: 1000

成功: 进程退出代码 0.


结果读写锁后发现每次结果都是1000.








  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值