golang 如何判断一个 goroutine 函数执行完成?

用 golang 的一个定时任务的第三方包,每隔 5s 执行 foo 函数,如下:

func foo() {
    onlineRooms := getOnlineRooms()
    for _, room := range onlineRooms {
        go doSomeThing(room)
    }
}

这里取出所有在线的房间ID,然后启用 goroutine 执行 doSomeThing 函数,这个函数里有计算,从 Redis,MySQL 读写数据等操作,如果第一轮调用没执行完,就开始第二轮调用,就会有计算错误。

那么我想每次定时任务来的时候,判断这个函数有没有执行完,如果没有执行完就不重新调用,否则才调用,在 golang 中如何实现这个判断呢?

阅读 8.6k
6 个回答

sync.WaitGroup 可以满足你的需求,以下是示例代码片段

wg = &sync.WaitGroup{}

func foo() {
    onlineRooms := getOnlineRooms()
    for _, room := range onlineRooms {
        wg.Add(1)
        go doSomeThing(room)
    }
    wg.Wait() // 所有计算做完,才会退出函数
}

func doSomeThing(room) {
    defer wg.Done()
    // do something
}

提供一个简单便于理解方案:

func foo() {
    onlineRooms := getOnlineRooms()
    for _, room := range onlineRooms {
        go doSomeThing(room)
    }
}

func doSomeThing(room Room) {
    //把redis操作换成全局变量亦可
    if redis.Get(room){
        return
    }
    redis.Set(room,true)
    defer redis.Set(room,false)
}

使用 sync.WaitGroup

package main

import (
    "fmt"
    "sync"
)

var wg *sync.WaitGroup

func main() {
    wg = &sync.WaitGroup{}
    for {
        wg.Wait()
        wg.Add(1)
        go test()
    }
    fmt.Println("vim-go")
}
func test() {
    //do something
    wg.Done()
}

可以在room里加一个字段记录操作是否完成

func foo() {
    onlineRooms := getOnlineRooms()
    for _, room := range onlineRooms {
        if room.Done {
            go doSomeThing(room)
        }
    }
}

可以用chan来解决

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题