Home >Backend Development >Golang >How to Gracefully Wait for Go Routines to Finish?

How to Gracefully Wait for Go Routines to Finish?

Barbara Streisand
Barbara StreisandOriginal
2024-12-07 16:34:15236browse

How to Gracefully Wait for Go Routines to Finish?

How to Gracefully Wait for Go Routines to Finish

In Go, concurrency is achieved through goroutines, which are lightweight threads that run concurrently with the main routine. To ensure that the program doesn't exit before all goroutines have completed their tasks, it's crucial to properly wait for them to finish.

Using a Channel to Signal Completion

One common approach to waiting for goroutines is to use a boolean channel. When a goroutine completes its task, it sends a true value to the channel, and the main routine waits for that value by receiving from the channel.

func do_stuff(done chan bool) {
    fmt.Println("Doing stuff")
    done <- true
}

func main() {
    fmt.Println("Main")
    done := make(chan bool)
    go do_stuff(done)
    <-done
}

Why does <-done work?

<-done is a blocking receive operation. This means that the main routine will wait until a value is sent to the done channel. Since the do_stuff goroutine explicitly sends a true value to the channel when it's finished, the main routine will receive it and continue execution.

What happens if we uncomment the last line?

If we uncomment the last line, we get a deadlock error because the channel is empty and no other goroutine is sending values to it. Therefore, the main routine will wait infinitely for a value to receive, resulting in a deadlock.

Alternative Approach Using Sync Package

For more complex concurrency scenarios, the sync package provides convenient synchronization mechanisms. For instance, if you need to parallelize a series of long-running functions, the following code snippet demonstrates how to use the sync.WaitGroup type:

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            longOp()
            wg.Done()
        }()
    }

    // will wait until wg.Done is called 10 times
    // since we made wg.Add(1) call 10 times
    wg.Wait()
}

func longOp() {
    time.Sleep(time.Second * 2)
    fmt.Println("long op done")
}

In this example, the WaitGroup ensures that the main routine doesn't exit until all goroutines have called wg.Done.

The above is the detailed content of How to Gracefully Wait for Go Routines to Finish?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn