Home  >  Article  >  Backend Development  >  How to control the life cycle of Golang coroutines?

How to control the life cycle of Golang coroutines?

WBOY
WBOYOriginal
2024-05-31 18:05:001077browse

Controlling the life cycle of the Go coroutine can be done in the following ways: Create a coroutine: Use the go keyword to start a new task. Terminate coroutines: wait for all coroutines to complete, use sync.WaitGroup. Use channel closing signals. Use context context.Context.

如何控制 Golang 协程的生命周期?

How to control the life cycle of Go coroutines?

In the Go language, coroutines (also known as Goroutines) are lightweight concurrent execution bodies used to perform specific tasks without blocking the main thread. Managing the lifecycle of coroutines is critical to writing robust and maintainable parallel code.

Create a coroutine

Use the go keyword to create a coroutine. It starts a new task in the background so that the main thread can continue execution.

go func() {
    // 执行任务
}

Terminating the coroutine

Cannot terminate the coroutine directly, but there are the following methods to achieve this purpose indirectly:

Wait for all coroutines to complete

Use sync.WaitGroup Synchronization task completed:

import "sync"

var wg sync.WaitGroup

func main() {
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(i int) {
            // 执行任务
            wg.Done()
        }(i)
    }
    wg.Wait()
}

Use channel close signal

Use channel to send "close" signal to coroutine:

func main() {
    done := make(chan struct{})
    for i := 0; i < 5; i++ {
        go func(i int) {
            for {
                select {
                case <-done:
                    return // 协程停止
                default:
                    // 执行任务
                }
            }
        }(i)
    }
    close(done) // 向所有协程发送"关闭"信号
}

Use context

Use context.Context to manage the execution of the coroutine. When the context is canceled, the coroutine will also terminate:

import "context"

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    for i := 0; i < 5; i++ {
        go func(i int) {
            for {
                select {
                case <-ctx.Done():
                    return // 协程停止
                default:
                    // 执行任务
                }
            }
        }(i)
    }
    cancel() // 取消上下文
}

Actual case

The following It is a practical case of using channel closing signal:

package main

import "fmt"
import "time"

func main() {
    // 使用信道告诉协程何时退出
    stop := make(chan struct{})

    // 创建 5 个协程
    for i := 0; i < 5; i++ {
        go func(i int) {
            for {
                // 检查是否已经收到退出信号
                select {
                case <-stop:
                    fmt.Printf("协程 %d 已退出\n", i)
                    return
                default:
                    fmt.Printf("协程 %d 正在运行\n", i)
                    time.Sleep(time.Second)
                }
            }
        }(i)
    }

    // 运行 5 秒,然后发送退出信号
    time.Sleep(time.Second * 5)
    close(stop)

    // 等待所有协程退出
    time.Sleep(time.Second * 1)
}

The above is the detailed content of How to control the life cycle of Golang coroutines?. 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