Home >Backend Development >Golang >How to stop goroutine in golang (four methods)

How to stop goroutine in golang (four methods)

PHPz
PHPzOriginal
2023-04-11 10:42:061369browse

Golang is a language designed to build highly concurrent and efficient programming. It provides a convenient and efficient goroutine mechanism, which can greatly improve the running efficiency and performance of the program. However, when we use goroutine, there are some things we need to pay attention to, such as how to stop the goroutine from running. The following will focus on how to stop goroutine.

The basics of Goroutine

Before understanding how to stop goroutine, we need to first understand the basic knowledge of goroutine. Goroutine is an implementation of lightweight threads in the Golang language and can run on one or more threads. It is managed by the Go runtime system and is an independent, lightweight execution unit. Different from traditional threads, goroutine is automatically scheduled by the Go runtime system when running, and its scheduling model is also very efficient. It can not only support high concurrency well, but also take full advantage of multi-core CPUs.

How to create a goroutine

In the Go language, we can create a goroutine in the following two common ways:

  1. Use the go keyword
go func() {
    //goroutine运行的代码
}()
  1. Use go keyword and function name
func myFunc() {
    //goroutine运行的代码
}

go myFunc()

How to stop goroutine

Stopping goroutine is a more complicated problem, because goroutine does not have Provide explicit methods to terminate and pause. This is because one of the design goals of the Go language is to prevent goroutines from being blocked while running, so we need some special techniques to stop them.

In Go language, we have the following four ways to stop goroutine:

1. Using channel

Using channel is the simplest and safest way to stop goroutine. one. We can create a bool type channel. When we need to stop the goroutine, we send a signal to this channel. The goroutine can exit normally after receiving the signal.

func worker(stopChan chan bool) {
    for {
        select {
        case <-stopChan:
            fmt.Println("worker stopped")
            return
        default:
            fmt.Println("worker is running")
            time.Sleep(time.Second)
        }
    }
}

func main() {
    stopChan := make(chan bool)
    go worker(stopChan)
    time.Sleep(3 * time.Second)
    stopChan <- true
    time.Sleep(time.Second)
}
2. Using context

In Go1.7, the context package was added to the standard library, providing a new method of suspending and canceling goroutines. We can pass in a Context parameter in each goroutine, and then perform a cancel operation on this Context variable when we need to stop the goroutine.

func worker(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println("worker stopped")
            return
        default:
            fmt.Println("worker is running")
            time.Sleep(time.Second)
        }
    }
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    go worker(ctx)
    time.Sleep(3 * time.Second)
    cancel()
    time.Sleep(time.Second)
}
3. Use Mutex and WaitGroup

To control the stopping of goroutine through shared variables, this method requires the use of Mutex and WaitGroup in the sync package. Mutex is used to protect the reading and writing of shared variables, and WaitGroup is used to wait for all goroutines to complete.

var wg sync.WaitGroup
var stop bool
var mutex sync.Mutex

func worker() {
    defer wg.Done()
    for {
        mutex.Lock()
        if stop {
            mutex.Unlock()
            fmt.Println("worker stopped")
            return
        }
        fmt.Println("worker is running")
        mutex.Unlock()
        time.Sleep(time.Second)
    }
}

func main() {
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go worker()
    }
    time.Sleep(3 * time.Second)
    mutex.Lock()
    stop = true
    mutex.Unlock()
    wg.Wait()
    time.Sleep(time.Second)
}
4. Using the runtime package

The method of using the runtime package is a little more troublesome. In the code running by the goroutine, you need to check the global variables regularly, and then when you need to stop the goroutine, Use the functions in the runtime package to force it to terminate.

var stop bool

func worker() {
    for {
        if stop {
            fmt.Println("worker stopped")
            return
        }
        fmt.Println("worker is running")
        time.Sleep(time.Second)
    }
}

func main() {
    go worker()
    time.Sleep(3 * time.Second)
    stop = true
    time.Sleep(time.Second)
    runtime.Goexit() //退出当前运行的goroutine
}

Summary

Using goroutine can greatly improve the concurrency performance of the program, but controlling the operation of goroutine is also extremely important. How to stop goroutine gracefully has become a problem we must face. . The above four methods have their own advantages and applicable scenarios, and you need to choose the most suitable method according to the specific situation.

The above is the detailed content of How to stop goroutine in golang (four methods). 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