golang sync.Once
时间: 2023-10-10 08:06:45 浏览: 201
sync.Once 是 golang 中的一个同步原语,它能够确保某个函数只被执行一次。它的使用方式是通过一个 sync.Once 结构体对象来调用函数的方法 Do,只有第一次调用 Do 方法时,才会执行传入的函数。
下面是一个使用 sync.Once 的示例代码:
```go
package main
import (
"fmt"
"sync"
)
var once sync.Once
func main() {
// 定义一个匿名函数,只会执行一次
onceFunc := func() {
fmt.Println("This function will only be executed once.")
}
// 多个 goroutine 同时调用 Do 方法,但只有第一个调用会执行函数
go once.Do(onceFunc)
go once.Do(onceFunc)
// 等待 goroutine 执行完成
time.Sleep(time.Second)
}
```
在上面的示例中,我们定义了一个匿名函数 onceFunc,并将其作为参数传递给 once.Do 方法。当多个 goroutine 同时调用 Do 方法时,只有第一个调用会执行函数 onceFunc,后续的调用会被忽略。
这样可以确保某些只需要执行一次的操作只会被执行一次,例如初始化全局变量或加载配置文件等。
相关问题
var UserSrvOnce sync.Once
引用\[1\]和\[2\]提供了关于sync.Once的使用示例。sync.Once是Go语言中的一个同步原语,用于确保某个操作只执行一次。在示例中,sync.Once被用来保证onceBody函数只被执行一次。通过调用once.Do(onceBody),可以确保onceBody函数只会在第一次调用时执行,后续的调用都会被忽略。这在并发编程中非常有用,可以避免重复执行某个操作。
引用\[3\]提供了一个更具体的示例,展示了如何使用sync.Once来获取一个客户端对象。在这个示例中,getMyClient函数使用sync.Once来确保只有在第一次调用时才会创建一个新的MyClient对象,后续的调用都会返回同一个对象。
根据提供的代码片段,var UserSrvOnce sync.Once是一个sync.Once类型的变量声明。根据sync.Once的用途,可以推测UserSrvOnce可能是用来确保某个操作只执行一次的。具体的操作需要根据代码的上下文来确定。
#### 引用[.reference_title]
- *1* [Golang sync.Once详解](https://blog.csdn.net/neweastsun/article/details/127562284)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item]
- *2* *3* [Golang sync.Once 简介与用法](https://blog.csdn.net/K346K346/article/details/87622326)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item]
[ .reference_list ]
golang sync
### Golang 中 `sync` 包的用法
#### 错误处理与同步原语
在 Go 语言中,`sync` 包提供了基本的同步原语,如互斥锁(Mutex)、读写锁(RWMutex),以及用于 goroutine 协调的 WaitGroup 和 Once 类型。这些工具帮助开发者编写线程安全的应用程序。
对于并发编程中的错误处理,通常建议将错误返回给调用者而不是直接 panic[^1]:
```go
func safeOperation() (result int, err error) {
mu.Lock()
defer mu.Unlock()
// 执行可能失败的操作
result, err = doSomethingThatMightFail()
if err != nil {
return 0, fmt.Errorf("operation failed: %w", err)
}
return result, nil
}
```
#### 使用 Mutex 实现数据保护
为了防止多个 goroutines 同时访问共享资源而导致的竞争条件,可以使用 `sync.Mutex` 或 `sync.RWMutex` 来锁定临界区。下面是一个简单的计数器例子,展示了如何利用 mutex 进行同步控制[^3]:
```go
type Counter struct {
value int
sync.Mutex
}
// Increment increases counter by one.
func (c *Counter) Increment() {
c.Lock()
defer c.Unlock()
c.value++
}
// Value returns current count without holding lock.
func (c *Counter) Value() int {
c.Lock()
v := c.value
c.Unlock()
return v
}
```
#### 利用 WaitGroup 等待一组 Goroutines 完成
当有若干个并行的任务需要完成后再继续执行后续逻辑时,可以通过创建一个 `WaitGroup` 对象来跟踪它们的状态,并等待所有任务结束之后再释放阻塞状态:
```go
var wg sync.WaitGroup
for i := 0; i < n; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
// Perform work here...
processItem(i)
}(i)
}
wg.Wait() // Block until all workers are done.
fmt.Println("All tasks have been completed.")
```
#### 使用 Once 确保初始化只发生一次
有时希望某些昂贵操作仅被执行一次,比如加载配置文件或建立数据库连接池等场景下非常有用。此时就可以借助于 `sync.Once` 提供的功能,在第一次调用 Do 方法的时候会触发指定函数的运行,而后的任何重复调用都不会再次执行该动作[^2]:
```go
var config ConfigType
var onceConfig sync.Once
getConfig := func() *ConfigType {
onceConfig.Do(func(){
// Load configuration from file or other sources only ONCE.
config.loadFromFileSystem()
})
return &config
}
```
阅读全文
相关推荐















