【问题标题】:How to ensure a goroutine exits before main()? without using WaitGroup [closed]如何确保 goroutine 在 main() 之前退出?不使用 WaitGroup [关闭]
【发布时间】:2021-01-27 05:59:21
【问题描述】:

来自以下代码:

package main

import (
    "fmt"
    "runtime"
    "time"
)

var signal = make(chan struct{})

func printNumbers() {

    counter := 1
    for {
        select {
        case <-signal:
            fmt.Println("Received signal")
            // do some housekeeping
            return
        default:
            time.Sleep(100 * time.Millisecond)
            counter++
        }
    }
}

func main() {

    go printNumbers()

    fmt.Println("Before: active go-routines", runtime.NumGoroutine())
    time.Sleep(time.Second)
    close(signal)
    //time.Sleep(1 * time.Second) do some work
    fmt.Println("After: active go-routines", runtime.NumGoroutine())
    fmt.Println("Program exited")
}

实际输出为:

Before: active go-routines 2
After: active go-routines 2
Program exited
Received signal

预期输出是:

Before: active go-routines 2
After: active go-routines 1   
Program exited
Received signal

主要是活动的go-routines(after)输出应该是1

如何确保main() go-routine 仅在其他 go-routine 退出后才退出?

【问题讨论】:

    标签: go channel goroutine


    【解决方案1】:

    使用一个通道来等待一个 goroutine 很容易,如下所示。等待多个 goroutine 时使用 WaitGroup。

    package main
    
    import (
        "fmt"
        "runtime"
        "time"
    )
    
    var signal = make(chan struct{})
    var done = make(chan struct{})   // closed when goroutine is done.
    
    func printNumbers() {
        defer close(done)
        counter := 1
        for {
            select {
            case <-signal:
                fmt.Println("Received signal")
                // do some housekeeping
                return
            default:
                time.Sleep(100 * time.Millisecond)
                counter++
            }
        }
    }
    
    func main() {
    
        go printNumbers()
    
        fmt.Println("Before: active go-routines", runtime.NumGoroutine())
        time.Sleep(time.Second)
        close(signal)
        //time.Sleep(1 * time.Second) do some work
        <-done   // wait for the goroutine to be returning.
        fmt.Println("After: active go-routines", runtime.NumGoroutine())
        fmt.Println("Program exited")
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2023-03-12
      • 2013-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多