gpt4 book ai didi

go - 如何协调多个 goroutine 的关闭

转载 作者:IT王子 更新时间:2023-10-29 00:47:49 27 4
gpt4 key购买 nike

假设我有一个函数

type Foo struct {}

func (a *Foo) Bar() {
// some expensive work - does some calls to redis
}

它在我的应用程序的某个时刻在 goroutine 中执行。许多这些可能在任何给定点执行。在应用程序终止之前,我想确保所有剩余的 goroutines 都已完成它们的工作。

我可以做这样的事情吗:

type Foo struct {
wg sync.WaitGroup
}

func (a *Foo) Close() {
a.wg.Wait()
}

func (a *Foo) Bar() {
a.wg.Add(1)
defer a.wg.Done()

// some expensive work - does some calls to redis
}

这里假设 Bar 在一个 goroutine 中执行,其中许多 goroutine 可能在给定时间运行,并且一旦调用 Close 就不应调用 Bar 并且在 sigterm 或 sigint 上调用 Close。

这有意义吗?

通常我会看到 Bar 函数看起来像这样:

func (a *Foo) Bar() {
a.wg.Add(1)

go func() {
defer a.wg.Done()
// some expensive work - does some calls to redis
}()
}

最佳答案

是的,WaitGroup 是正确的答案。根据 doc,您可以在计数器大于零的任何时候使用 WaitGroup.Add .

Note that calls with a positive delta that occur when the counter is zero must happen before a Wait. Calls with a negative delta, or calls with a positive delta that start when the counter is greater than zero, may happen at any time. Typically this means the calls to Add should execute before the statement creating the goroutine or other event to be waited for. If a WaitGroup is reused to wait for several independent sets of events, new Add calls must happen after all previous Wait calls have returned. See the WaitGroup example.

但有一个技巧是,在调用 Close 之前,您应该始终保持计数器大于零。这通常意味着您应该在 NewFoo(或类似的东西)中调用 wg.Add 并在 Close 中调用 wg.Done >。为了防止多次调用 Done 破坏 WaitGroup ,您应该将 Close 包装到 sync.Once 中。您可能还想阻止调用新的 Bar()

关于go - 如何协调多个 goroutine 的关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54547298/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com