go - 如何在并发环境中为每个关键参数运行一次 golang 函数调用?

标签 go concurrency

这个例子似乎只获取一次数据,但我不认为它会在后台为每个 key 同时调用一个 fetchDataInBackground 函数。

func Get(key string){
    ...
    if itIsTheTimeToRefreshData{
         var once sync.Once
         onceBody := func() {
            fetchDataInBackground()
         }
         go func() {
            once.Do(onceBody)
         }()
     }
     ...
 }

我需要做的是将每个 Once 实例分配给一个 key 以便可以同时完成不同键的所有获取数据。 我该怎么做?

最佳答案

我认为 sync.Once 不适合这样的任务。您需要为每个键分别维护一些标志(“一次”)。具有互斥访问权限的 map 是可能的解决方案之一。

完整的工作示例:

package main

import (
        "fmt"
        "sync"
        "time"
)

var once map[string]bool
var onceMutex sync.Mutex
var itIsTheTimeToRefreshData = true

func Get(key string) {
        fmt.Printf("Access for key: %s\n", key)
        if itIsTheTimeToRefreshData {
                onceBody := func() {
                        fmt.Printf("Only once for key: %s\n", key)
                        //fetchDataInBackground()
                }

                onceMutex.Lock()
                if !once[key] { // is it first time?
                        once[key] = true
                        onceMutex.Unlock()

                        // refresh something here
                        go onceBody()
                } else {
                        onceMutex.Unlock()
                }
        }
}

func main() {
        once = make(map[string]bool)

        // do it first time in parallel
        for i := 0; i < 10; i++ {
                key := fmt.Sprintf("i%d", i)
                go func(key string) {
                        Get(key)
                }(key)
        }
        // and another time
        for i := 0; i < 10; i++ {
                key := fmt.Sprintf("i%d", i)
                go func(key string) {
                        Get(key)
                }(key)
        }
        fmt.Println("All requested.")
        time.Sleep(1 * time.Second)
}

关于go - 如何在并发环境中为每个关键参数运行一次 golang 函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40694698/

相关文章:

node.js - NodeJS 向其他服务发出的最大限制

java - 如何使用多线程使我的应用程序更快

go - gorm无效的内存地址或nil指针取消引用

go - 编写模块?

function - 语法错误 : Non-declaration statement outside function body

java - 嵌套 Scala Future 是否需要托管阻塞?

java - Java 中的多线程状态可见性 : is there a way to turn the JVM into the worst case scenario?

http - 你如何使用 Go 和 http 包删除 cookie?

Google Calendar API invalid_grant 获取 token (Golang)

c# - 在 C# 中使用 ConcurrentStack 时出现奇怪的异常