dongyi1159 2016-11-19 15:38
浏览 35
已采纳

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

This example seems to fetch data once, but I don't think it will invoke a fetchDataInBackground function in background for each key concurrently.

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

what I need to do is to assign each Once instance to a key so that all fetch data for different keys can be done concurrently. how do I do that?

  • 写回答

1条回答 默认 最新

  • dqpu4988 2016-11-19 16:13
    关注

    I think sync.Once is not well for such task. You need to maintain some flag ("once") for each key individually. Map with mutexed access is one of possible solutions.

    Full working example:

    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
    ", key)
            if itIsTheTimeToRefreshData {
                    onceBody := func() {
                            fmt.Printf("Only once for key: %s
    ", 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)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 vs2022无法联网
  • ¥15 TCP的客户端和服务器的互联
  • ¥15 VB.NET操作免驱摄像头
  • ¥15 笔记本上移动热点开关状态查询
  • ¥85 类鸟群Boids——仿真鸟群避障的相关问题
  • ¥15 CFEDEM自带算例错误,如何解决?
  • ¥15 有没有会使用flac3d软件的家人
  • ¥20 360摄像头无法解绑使用,请教解绑当前账号绑定问题,
  • ¥15 docker实践项目
  • ¥15 利用pthon计算薄膜结构的光导纳