深入解读Go并发库singleflight:shared参数的真相
Go语言的singleflight库有效防止对相同键的重复计算。本文将深入分析singleflight.Do函数的第三个返回值shared,澄清其并非指示多个goroutine同时执行任务的常见误解。
让我们先看一个代码示例:
package main import ( "fmt" "sync" "time" "golang.org/x/sync/singleflight" ) func main() { g := singleflight.Group{} wg := sync.WaitGroup{} for i := 0; i < 5; i++ { wg.Add(1) go func(i int) { defer wg.Done() val, _, shared := g.Do(fmt.Sprintf("key%d", i), func() (interface{}, error) { time.Sleep(1 * time.Second) return fmt.Sprintf("result%d", i), nil }) fmt.Printf("goroutine %d: val=%v, shared=%t\n", i, val, shared) }(i) } wg.Wait() }
这段代码模拟多个goroutine并发调用一个耗时函数,使用singleflight.Group确保该函数仅执行一次。 许多开发者误解shared表示多个goroutine是否同时执行该函数,但事实并非如此。
singleflight.Do函数的文档明确指出:the return value shared indicates whether v was given to multiple callers. 这意味着shared仅指示返回值v是否被多个调用者共享。
只有当一个goroutine执行耗时函数时,其他goroutine都在等待结果,此时v才由该goroutine独享,shared返回false。但在并发场景下,多个goroutine几乎同时发起请求,第一个执行完成后,其余goroutine直接复用其结果,因此shared几乎总是返回true。 这并非错误,而是singleflight库的设计初衷。shared的意义在于告知调用者其获得的结果是否来自缓存,而非多个goroutine是否同时执行了任务。
以上就是Go并发库singleflight源码解读:singleflight.Do函数的shared参数究竟代表什么?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号