Home  >  Article  >  Backend Development  >  How to close coroutine in golang

How to close coroutine in golang

PHPz
PHPzOriginal
2023-03-30 09:07:273266browse

With the popularity of Golang in recent years, more and more people have begun to understand and use Golang. Among them, coroutines are a major feature of the Golang language. Its lightweight thread implementation makes the use of coroutines very flexible and efficient. However, when using coroutines, it is sometimes necessary to manually close the coroutines in order to release resources and avoid problems such as memory leaks. This article will introduce several methods and techniques for closing coroutines in Golang.

1. Use channel to close coroutine

In Golang, you can use channel to close coroutine. This method is very simple. You only need to define a bool type channel to control the closing of the coroutine, and continuously detect the status of this channel in the coroutine. When the channel is closed, the coroutine will exit.

The following is a sample code:

package main

import (
    "fmt"
    "time"
)

func worker(stop chan bool) {
    for {
        select {
        case <-stop:
            fmt.Println("worker stopped")
            return
        default:
            fmt.Println("working...")
            time.Sleep(1 * time.Second)
        }
    }
}

func main() {
    stop := make(chan bool)
    go worker(stop)

    time.Sleep(5 * time.Second)
    fmt.Println("stop worker")
    close(stop)

    time.Sleep(5 * time.Second)
    fmt.Println("program exited")
}

In the above code, we define a worker function as a coroutine and pass in a stop chan bool type channel. In the worker function, we use the select statement to listen to the stop channel. If the channel is closed, exit the coroutine. In the main function, we created a stop channel and started a worker coroutine through the go keyword. After waiting for 5 seconds, we close the stop channel in the main function, thereby stopping the worker coroutine. After a final wait of 5 seconds, the program exits.

2. Use context to cancel coroutines

In addition to using channels, context can also be used in Golang to cancel coroutines. Context provides a standard method that allows passing timeouts, cancellation signals, and other values ​​on the request scope of the running coroutine.

The following is a sample code:

package main

import (
    "context"
    "fmt"
    "time"
)

func worker(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println("worker canceled")
            return
        default:
            fmt.Println("working...")
            time.Sleep(1 * time.Second)
        }
    }
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    go worker(ctx)

    time.Sleep(5 * time.Second)
    fmt.Println("cancel worker")
    cancel()

    time.Sleep(5 * time.Second)
    fmt.Println("program exited")
}

In the above code, we use the context.WithCancel function to create a context with a cancellation signal and pass it in to the worker function. In the worker function, we use the select statement to listen to the context.Done() channel. If the context is canceled, exit the coroutine. In the main function, we call the cancel function to cancel the context and thereby stop the worker coroutine.

3. Use sync.WaitGroup to implement coroutine waiting

In Golang, using sync.WaitGroup to implement coroutine waiting is also a common method. When the coroutine starts, the WaitGroup counter will be incremented by 1; when the coroutine exits, the counter will be decremented by 1. When the counter reaches 0, it indicates that all coroutines have exited and the main function can continue execution.

The following is a sample code:

package main

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

func worker(wg *sync.WaitGroup, stop chan bool) {
    defer wg.Done()

    for {
        select {
        case <-stop:
            fmt.Println("worker stopped")
            return
        default:
            fmt.Println("working...")
            time.Sleep(1 * time.Second)
        }
    }
}

func main() {
    wg := sync.WaitGroup{}
    stop := make(chan bool)

    wg.Add(1)
    go worker(&wg, stop)

    time.Sleep(5 * time.Second)
    fmt.Println("stop worker")
    stop <- true

    wg.Wait()
    fmt.Println("program exited")
}

In the above code, we use sync.WaitGroup to wait for the exit of the worker coroutine. In the worker function, we use the defer statement to decrement the WaitGroup counter when the coroutine exits. In the main function, we first increase the WaitGroup counter by 1, and then call the go keyword to start the worker coroutine. After waiting for 5 seconds, we send a bool type message to the stop channel to stop the worker coroutine. Finally, we wait for the WaitGroup counter to become 0, thus ending the program.

In summary, this article introduces several methods of closing coroutines in Golang, including using channels to close coroutines, using context to cancel coroutines, and using sync.WaitGroup to implement coroutine waiting. In actual projects, it is necessary to choose the appropriate method to close coroutines based on business scenarios and specific needs to avoid resource leaks and improve program performance.

The above is the detailed content of How to close coroutine in golang. 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