首页 > Go 分布式学习利器(18)-- Go并发编程之lock+WaitGroup实现线程安全

Go 分布式学习利器(18)-- Go并发编程之lock+WaitGroup实现线程安全

Go语言中通过Groutine 启动一个Go协程,不同协程之间是并发执行的,就像C++/Java中线程之间线程安全是一个常见的问题。

如下Go 语言代码:

func TestConcurrent(t *testing.T) { var counter int = 0for i := 0;i < 5000; i ++{ go func() {  // 启动groutine 进行变量的自增counter ++}()}time.Sleep(time.Second * 1)t.Logf("Counter = %d", counter) 
}

最后的结果输出如下:

=== RUN   TestConcurrentconcurrent_test.go:18: Counter = 4663
--- PASS: TestConcurrent (1.00s)

希望变量Counter的结果是5000,最终因为协程之间并发访问共享内存的原因导致部分协程执行的结果没有得到变更,从而数据不符合预期。

Go中提供了MutexRWMutex ,来实现锁功能。前者就是正常的Lock, Unlock;后者提供了读写锁,在协程读写分离中提供了读读互不影响,读写互斥。

如下测试代码:

func TestMutex(t *testing.T) { var counter int = 0// var mu sync.Mutex // mutex lockvar mu sync.RWMutex // rwmutex lockfor i := 0;i < 5000; i ++{ go func() { // defer mutex unlock// 如果协程异常退出,能够释放锁defer func() {  mu.Unlock()}()mu.Lock()counter ++}()}time.Sleep(time.Second * 1)t.Logf("Counter = %d", counter)
}

最终输出如下,通过mutex 实现了变量访问的安全:

=== RUN   TestMutexconcurrent_test.go:36: Counter = 5000
--- PASS: TestMutex (1.01s)

可以看到如上代码需要通过Sleep来让所有的协程都执行完,显然不合理。、

假如有更多的协程,这个sleep时间还需要程序员来修改,Go语言提供了WaitGroup机制,就像是C++中的条件变量,主线程可以等待在条件变量上,当线程执行完可以通过条件变量唤醒主线程继续执行。

var wg sync.WaitGroup 声明一个WaitGroup变量

通过wg.Add(1)wg.Done() 来检测线程的完成情况,wg.Wait()表示主线程等待在wg变量上

func TestWaitGroup(t *testing.T) { var counter int = 0var mu sync.RWMutex // rw lock, 读写互斥var wg sync.WaitGroupfor i := 0;i < 5000; i ++{ wg.Add(1) go func() { defer func() { mu.Unlock()}()mu.Lock()counter ++wg.Done() // wg.Add(-1)}()}wg.Wait()t.Logf("Counter = %d", counter)
}

输出如下,可以看到TestWaitGroup 函数的执行时间很快,不需要Sleep方式来消耗更多的时间使程序被动执行完毕。

=== RUN   TestWaitGroupconcurrent_test.go:57: Counter = 5000
--- PASS: TestWaitGroup (0.00s)

更多相关:

  • 师弟总结的已经很好了 或者: 原工程需要导出的函数: extern "C" __declspec(dllexport) void Func(); 现工程导入这个函数: extern "C" __declspec(dllimport) void Func();...

  • 有使用过JS的朋友,相信都知道function。JS中的function是可以在里面在定义一个作为内部使用的。有时为了控制作用域,或者这种小函数只在这个函数体内会使用,所以就不希望在外部在作额外的定义。那C#中有没有这样类似的方式呢?答案是有的。 在C#中要实现,需要用到的是委托和lambda表达式。对于lambda表达式,是可以实...