Go 语言入门很简单:并发同步的几种方式
  TEZNKK3IfmPf 2023年11月14日 21 0

Go 语言并发同步的方式

Golang Sync 包提供了同步原语,例如:

  • ​mutex​
  • ​Waitgroup​
  • ​Pool​
  • ​Read​
  • ​Write mutex​
  • condition variables条件变量

​sync.Mutex​​ 提供了一个互斥原语,它允许共享资源的互斥,防止竞争条件。

 

package main

import (
"sync"
)

func main() {

i := 10
mutex := &sync.Mutex{}
mutex.Lock()
i++
mutex.Unlock()
}

读写锁

​sync.RWMutex​​ 提供读写锁,它提供了与原始互斥锁类似的方法,但可以使用 ​​RLock​​ 和 ​​RUnlock​​ 方法允许并发读取:

package main

import (
"sync"
)

func main() {

i := 10
mutex := &sync.RWMutex{}
mutex.Lock()
// only one goroutine can access this code at a time
i++
mutex.Unlock()

mutex.RUnlock()
i++ // concurrent reads
mutex.RUnlock()
}

上一个示例可以允许多个 goroutine 读取代码。与 ​​sync.Mutex​​ 不同,它一次只允许一个读取器和一个写入器。

 

Waitgroups

​sync.Waitgroup​​ 用于为 goroutine 提供阻塞机制。使用 Waitgroup,您可以阻止函数的执行,直到所有 goroutine 执行完毕。

它通过创建一个计数器来工作,该计数器保存要等待的 goroutine 的数量。一旦一个 goroutine 完成,计数器减 1。一旦计数器为 0,Waitgroup 就会解除对执行的阻塞。
要将值添加到 Waitgroup 计数器,我们可以使用 ​​Add()​​ 方法,该方法采用整数值。

要在完成后从计数器中删除一个 goroutine,我们使用 ​​Done()​​ 方法。例如:

 

package main

import (
"fmt"
"sync"
)

func main() {
wg := &sync.WaitGroup{}
for i := 0; i < 5; i++ {
wg.Add(1)
go func(x int) {
fmt.Printf("Worker: %d running\n", x)
wg.Done()
}(i)
}
wg.Wait()
}

在前面的示例中,我们通过使用 ​​Add()​​ 函数将 Waitgroup 计数器的值加 1。

一旦一个 goroutine 完成,我们使用 ​​Done()​​ 方法将计数器减 1。前面的代码应返回输出为:

 

Worker: 3 running
Worker: 1 running
Worker: 4 running
Worker: 0 running
Worker: 2 running

Once

​sync.Once​​ 原语确保一个函数只运行一次。一个例子如下所示:

 

package main

import (
"fmt"
"sync"
)

func main() {
var once sync.Once
RunOnce := func() {
fmt.Println("Run once")
}
done := make(chan string)
for i := 0; i < 5; i++ {
go func() {
once.Do(RunOnce)
done <- "Hi"
}()
}
for i := 0; i < 5; i++ {
<-done
}
}

运行该代码:

Run once

总结

本文涵盖了 Go sync 包提供的一些基本方法:如互斥锁、读写锁、等待组、Once 等同步原语的用法。更多原理和使用方法等待读者去探索。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月14日 0

暂无评论

TEZNKK3IfmPf