Home  >  Article  >  Backend Development  >  Go language document analysis: sync.Once function implements single execution

Go language document analysis: sync.Once function implements single execution

王林
王林Original
2023-11-03 08:28:501987browse

Go language document analysis: sync.Once function implements single execution

Go language document analysis: sync.Once function implements single execution and requires specific code examples

The sync package in Go language provides some functions for synchronous operations Functions and types. One very useful function is sync.Once, which ensures that an operation is performed only once. In this article, we will analyze the use of the sync.Once function in detail and provide some specific code examples.

The sync.Once function is defined as follows:

type Once struct {
    m    Mutex
    done uint32
}

func (o *Once) Do(f func()) {
    if atomic.LoadUint32(&o.done) == 1 {
        return
    }
    o.m.Lock()
    defer o.m.Unlock()
    if o.done == 0 {
        f()
        atomic.StoreUint32(&o.done, 1)
    }
}

As you can see, the sync.Once structure contains a mutex (Mutex) and a done flag to record whether the operation Already executed. The Do method of the Once structure is the core logic to achieve single execution.

The Do method first checks whether the done flag is 1 through the atomic operation atomic.LoadUint32. If it is 1, it means that the operation has been performed and returns directly. Otherwise, acquire the mutex and check again whether the done flag is 0. If it is 0, execute the passed-in function f and set the done flag to 1 through the atomic operation atomic.StoreUint32 to ensure that f will not be executed the next time it is called.

The following is a simple example that demonstrates how to use the sync.Once function to achieve a single execution:

package main

import (
    "fmt"
    "sync"
)

var once sync.Once

func main() {
    for i := 0; i < 5; i++ {
        // 只有第一次调用会执行
        once.Do(func() {
            fmt.Println("This will only print once.")
        })
    }
}

Run the above code, the output is as follows:

This will only print once.

You can see It turns out that although the once.Do method is called multiple times in the loop, only the first call will actually execute the function passed in, and subsequent calls will return directly without executing it again.

The sync.Once function has a wide range of usage scenarios. For example, when initializing a global variable, we usually want to perform the initialization only once, rather than initializing it every time the variable is accessed. At this point, you can use the sync.Once function to ensure that the initialization is only performed once.

var (
    data  []string
    once  sync.Once
)

func loadData() {
    // 模拟耗时的数据加载操作
    // 这里简单起见直接赋值
    data = []string{"Hello", "World"}
}

func getData() []string {
    once.Do(loadData)
    return data
}

func main() {
    fmt.Println(getData())
    fmt.Println(getData())
}

Run the above code, the output result is as follows:

[Hello World]
[Hello World]

By using the sync.Once function and the loadData function together, we ensure that the data variable will only be loaded when the getData function is called for the first time. Initialization, subsequent calls directly return the initialized data.

Summary:

The sync.Once function is one of the important functions in the Go language used to achieve single execution. It uses mutex locks and atomic operations to ensure that an operation is only executed once, which is very convenient and efficient. In actual development, we can make full use of the sync.Once function to optimize code logic, avoid repeated executions that affect performance, and ensure the uniqueness of operations.

Through the analysis and sample code of this article, I believe readers can master the usage of the sync.Once function and use it flexibly in actual projects. Let us work together to write higher quality Go language programs!

The above is the detailed content of Go language document analysis: sync.Once function implements single execution. 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