SoFunction
Updated on 2025-03-05

Concurrent programming in Go language

Used to ensure that an action is executed only once, it can be used in singleton mode, such as initializing configuration. We know that the init() function will only be executed once, but it ismain()The function is executed before. If you want to run an action only once during the code execution, you can use it., Let’s introduce how to use it.

Let’s take a look at the following code:

package main

import (
 "fmt"
 "sync"
)


func main() {
 var num = 6
 var once 

 add_one := func() {
  num = num + 1
 }

 minus_one := func() {
  num = num - 1
 } 

 (add_one)
 ("The num: %d\n", num)
 (minus_one)
 ("The num: %d\n", num)
}

Execution results:

The num: 7
The num: 7

Type provides aDoMethod, Do method only accepts one parameter, and the parameter type must befunc() , that is, a function without parameter declaration and result declaration.

DoThe method will only execute the function passed in when it is called for the first time, and will only execute once, and will not execute other functions. In the above example, even if the function passed in is different, only the function passed in the first time will be executed. If there are multiple functions that are executed only once, one needs to be assigned to each functionValue of type:

func main() {
 var num = 6
 var once1 
 var once2 

 add_one := func() {
  num = num + 1
 }

 minus_one := func() {
  num = num - 1
 } 

 (add_one)
 ("The num: %d\n", num)
 (minus_one)
 ("The num: %d\n", num)
}

Type is a structure type, and one is nameddoneofuint32Type field, and a mutex lockm

type Once struct {
 done uint32
 m    Mutex
}

doneThe value of the field can only be 0 or 1.DoAfter the first call of the method is completed,doneThe value of 1 becomes 1. The done value uses four bytesuint32The reason for type is to ensure that the operation on it is a "atomic operation", by callingatomic.LoadUint32The function gets its value. If it is 1, it will return directly and the function will not be executed.

If 0, the Do method will lock the field m immediately. If there is no lock here, multiplegoroutine When executing Do method at the same time, it is determined that it is 0, and the function will be executed.OnceIt is concurrently safe.

After locking, it will be checked againdoneThe value of the field, if the condition is met, execute the passed function and operate the function atomicallyatomic.StoreUint32WilldoneThe value of 1 is set to 1.

Here is the source code of Once:

func (o *Once) Do(f func()) {

 if atomic.LoadUint32(&) == 0 {
  (f)
 }
}

func (o *Once) doSlow(f func()) {
 ()
 defer ()
 if  == 0 {
  defer atomic.StoreUint32(&, 1)
  f()
 }
}

The source code is very concise and very similar to the singleton pattern in the GoF design pattern.

This is the end of this article about Go concurrent programming. For more related Go language content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!