返回
基于Go语言基础之并发基本同步原语展开探讨(二)
后端
2023-11-14 14:27:57
大家好,感谢大家持续关注。今天,将梳理出的 Go语言并发知识内容,分享给大家。 请多多指教,谢谢。 本文主要介绍 sync 标准库中基本同步原语 sync.Cond、sync.Once、sync.Pool 介绍及使用。
## 一、sync.Cond
sync.Cond 是一个条件变量,用于协调多个 goroutine 之间的通信。它可以实现等待、通知和广播等操作。
```go
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var cond sync.Cond
var mutex sync.Mutex
// 初始化一个 channel 用于存储需要处理的任务
taskQueue := make(chan int, 10)
// 启动一个 goroutine 来处理任务
go func() {
for {
// 尝试从 channel 中获取一个任务
select {
case task := <-taskQueue:
// 获取到任务后处理任务
fmt.Printf("Processing task %d\n", task)
default:
// 如果 channel 为空,则阻塞等待任务
cond.L.Lock()
cond.Wait()
cond.L.Unlock()
}
}
}()
// 主 goroutine 向 channel 中添加任务
for i := 0; i < 10; i++ {
mutex.Lock()
taskQueue <- i
mutex.Unlock()
// 唤醒等待任务处理的 goroutine
cond.Signal()
}
// 等待所有任务处理完成
cond.L.Lock()
for len(taskQueue) > 0 {
cond.Wait()
}
cond.L.Unlock()
fmt.Println("All tasks processed")
}
```
## 二、sync.Once
sync.Once 用于确保某个操作只执行一次。即使多个 goroutine 同时调用 sync.Once.Do() 方法,也只会执行一次操作。
```go
package main
import (
"fmt"
"sync"
)
var once sync.Once
func setup() {
fmt.Println("Setting up")
}
func main() {
// 多个 goroutine 同时调用 once.Do() 方法
for i := 0; i < 10; i++ {
go once.Do(setup)
}
// 主 goroutine 等待所有 goroutine 执行完成
time.Sleep(1 * time.Second)
fmt.Println("Setup completed")
}
```
## 三、sync.Pool
sync.Pool 用于管理对象池,可以提高对象的复用效率,减少创建和销毁对象的开销。
```go
package main
import (
"fmt"
"sync"
)
var pool sync.Pool
type MyStruct struct {
Value int
}
func main() {
// 初始化对象池
pool.New = func() interface{} {
return &MyStruct{}
}
// 从对象池中获取一个对象
obj := pool.Get().(*MyStruct)
obj.Value = 10
// 将对象归还给对象池
pool.Put(obj)
// 从对象池中再次获取一个对象
obj2 := pool.Get().(*MyStruct)
// 检查对象是否相同
if obj == obj2 {
fmt.Println("Same object")
} else {
fmt.Println("Different object")
}
}
```
## 总结
sync.Cond、sync.Once 和 sync.Pool 都是 Go 语言中非常有用的基本同步原语。它们可以帮助我们解决多种并发编程问题,提高程序的性能和可靠性。
## 致谢
感谢您的阅读。如果您有任何问题或建议,请随时留言。