Go Once: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 3: Line 3:
* [[Go_Language_Goroutines#Once|Goroutines | Synchronization]]
* [[Go_Language_Goroutines#Once|Goroutines | Synchronization]]
=Overview=
=Overview=
<code>Once</code> is a Go synchronization construct that is used when a piece of code must be executed only once. This is a useful idiom in initialization.
<code>Once</code> is a Go synchronization construct that is used when a piece of code must be executed only once. This is a useful idiom in initialization. Note that the code is executed synchronously, when it is executed: the invocation to <code>Once#Do()</code> executes in the same goroutine that makes the <code>Once#Do()</code> invocation.
 
=Example=
 
<syntaxhighlight lang='go'>
<syntaxhighlight lang='go'>
func initialization() {
var log Log
  fmt.Println("initializing ...")
var initLogOnce sync.Once
}


...
...
 
func GetLog() {
go func() {
   initLogOnce.Do(func() {
   ...
    log = ... // init the log
  once.Do(initialization)
  })
  ...
  return log // because the function passed to Do() executes synchronously, log will be initialized here.
}()
}
</syntaxhighlight>
</syntaxhighlight>
<font color=darkkhaki>Is the function executed synchronously?</font>


=Methods=
=Methods=

Revision as of 23:10, 16 January 2024

Internal

Overview

Once is a Go synchronization construct that is used when a piece of code must be executed only once. This is a useful idiom in initialization. Note that the code is executed synchronously, when it is executed: the invocation to Once#Do() executes in the same goroutine that makes the Once#Do() invocation.

Example

var log Log
var initLogOnce sync.Once

...
func GetLog() {
  initLogOnce.Do(func() {
     log = ... // init the log
  })
  return log // because the function passed to Do() executes synchronously, log will be initialized here.
}

Methods

Do()

The only argument of Do() is a function value, not a function invocation. Do() will use the function value to invoke the function, internally.

All invokers will block, except one, and they will be released after the one that does initialization finishes executing. The others will no execute.