Sync (synchronization)

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.
  1. Initialization
    The initialization of the program is performed in a separate goroutine. The goroutine created during initialization will be started after the first goroutine execution is completed for initialization.
    If package P imports packet Q, the INIT initialization function of packet q is executed before the initialization of the package p.
    The entry function of the program Main.main is started after all init functions have been executed.
    The newly created goroutines in any init function will be executed after all the INIT functions have been completed.
  2. Creation of Goroutine
    The GO statement used to start Goroutine runs before goroutine.
    For example, the following program:

    var a stringfunc f() { print(a)}func hello() { a = "hello, world" go f()}

    Calling the Hello function will print "Hello, world" at some point (possibly after the Hello function is returned).

  3. Channel communication pipeline communication
    Pipeline communication is the primary method for synchronizing between two goroutines. A send operation that is performed on a pipeline is associated with a receive operation for that pipeline, which usually corresponds to Goroutines. The send operation on the
    pipeline occurs before the receive of the pipeline is complete (happens before).
    For example, this program:

      var c = make (chan int, ten) var a stringfunc f () {a = "Hello, world" C <-0}func main () {go f () <-c print (a)}  
    The

    can ensure that "Hello, world" is output. Because the assignment of a occurs before the data is sent to pipe C, the send operation of the pipeline occurs before the pipeline receives completion. Therefore, at print time, A has been assigned a value. The
    receives data from a unbuffered pipeline before sending the data to the pipeline. The following is an example program:

      package Mainvar c = make (chan int) var a stringfunc f () {a = "Hello, World" <-c}func main () {g o f () c <-0 print (a)}  

    also ensures that the output is "Hello, world". Because A's assignment occurs before the data is received from the pipeline, the receive data operation from the pipeline occurs before the Unbuffered pipeline is sent. So, at print time, A has been assigned a value.
    If you are using a buffered pipeline (such as C = Make (chan int, 1)), you will not be guaranteed to output the "Hello, World" result (which could be an empty string, but it will certainly not be his unknown string, or cause the program to crash).

  4. Lock
    The package sync implements two types of locks: sync. Mutex and sync. Rwmutex.
    For any sync. Mutex or sync. Rwmutex variable L. If n < m, then the nth l.unlock () call occurs before the return of the second L.lock () call.
    For example, programs:

    var l sync.Mutexvar a stringfunc f() { a = "hello, world" l.Unlock()}func main() { l.Lock() go f() l.Lock() print(a)}

    You can ensure the output "Hello, World" results. Because, the first l.unlock () call (in the F function) occurs before the second l.lock () call (in the main function) is returned, which occurs before the print function call.
    For any call to a sync. Rwmutex variable L L.rlock, there is an n makes L. Rlock the nth call L.unlock occurs after (returns) and N +1 ' th before the match L. Runlock occurred calling L.lock.
    9.3.5. Once
    Package sync provides a way to initialize in multiple goroutines. Multiple goroutines can be passed through once. The Do (f) method calls the F function. However, the F function will only be executed once, and the other calls will be blocked until the only execution of F () is returned.
    Once. The only executed F () in Do (f) occurs in all once. Do (f) before returning.
    With code:

    var once sync.Oncevar a stringfunc setup() { a = "hello, world"}func doprint() { once.Do(setup) print(a)}func twoprint() { go doprint() go doprint()}

    Calling Twoprint will output "Hello, World" two times. The first time the Twoprint function runs setup only once.

The wrong way to sync

Note: The variable read operation can detect the write operation of the variable, but it is not guaranteed that the read operation of the variable must occur after the write operation.

For example:

package mainvar a, b intfunc f() {    a = 1    b = 2}func g() {    print(b)    print(a)}func main() {    go f()    g()}

The function g may output 2, or it may output 0.

This situation makes it necessary for us to avoid some seemingly reasonable usages.

Here, a duplicate detection method is used instead of synchronization. In the example, the Twoprint function may get the wrong value:

package mainimport (    "sync"    "time")var once sync.Oncevar a stringvar done boolfunc setup() {    a = "hello, world"    done = true}func doprint() {    if !done {        once.Do(setup)    }    print(a)}func twoprint() {    go doprint()    go doprint()}func main() {    twoprint()    time.Sleep(8000)}

In the Doprint function, the write-done hint has been assigned a value. However, there is no guarantee that the function may output a null value (in 2 goroutines simultaneously to the test statement).

Another error trap is busy waiting:

package mainvar a stringvar done boolfunc setup() {    a = "hello, world"    done = true}func main() {    go setup()    for !done {    }    print(a)}

We have no way of ensuring that the done value is modified in main and that a is modified so that the program can output an empty string. Worse, the main function may never know that done is modified because there is no synchronization between the two threads so that the main function never returns.

The following usage is essentially the same problem.

package maintype T struct {    msg string}var g *Tfunc setup() {    t := new(T)    t.msg = "hello, world"    g = t}func main() {    go setup()    for g == nil {    }    print(g.msg)}

Even if main observes the G! = Nil condition and exits the loop, it does not guarantee that it sees the result after the initialization of the g.msg.

In these examples, there is only one workaround: Synchronize with the display.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.