【问题标题】:Concurrent tasks but only for different type of tasks并发任务,但仅适用于不同类型的任务
【发布时间】:2023-03-25 01:30:01
【问题描述】:

我有以下用例,我很难确定正确的并发模式。

我有一项服务,其中包含要执行的计算任务列表:

  • 有些执行速度很快(几秒钟),有些可能需要几个小时
  • 我从不希望同一任务同时执行两次
  • 不同的任务可以并行执行
  • 如果一个任务应该每小时刷新一次,但在某些时候,它需要超过 1 小时才能执行,我想放弃新的执行但将其记录在某个地方
  • 我想让任务超时

当然,我可以使用外部库。

我查看了singleflight,但这似乎是针对缓存,并且任务的新执行将被阻止,直到该任务完成计算。就我而言,我想记录它已经在计算但丢弃新执行的事实(或者只是不执行)。

【问题讨论】:

  • 太棒了!这很有意义,非常感谢!
  • @Mike:goroutine 必须告诉其他人它已经完成了。这通常使用 WaitGroup 或通道之类的东西来完成。
  • 如果您继续添加您的答案,我会接受!

标签: go concurrency


【解决方案1】:

维护正在进行的任务的地图。添加任务时,检查地图并记录任务是否正在进行;将任务添加到地图。完成后从地图中删除任务。

这是一个假设任务由string 标识并由func() 实现的示例。

var (
    mu         sync.Mutex
    inProgress = map[string]bool{}
)

func startTask(id string, fn func()) {
    mu.Lock()
    ip := inProgress[id]
    if !ip {
        inProgress[id] = true
    }
    mu.Unlock()
    if ip {
        log.Printf("task %s in progress", id)
    } else {
        go func() {
            fn()
            mu.Lock()
            delete(inProgress, id)
            mu.Unlock()
        }()
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-07
    • 2014-07-17
    • 2017-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多