Home > Backend Development > Golang > GO:lack of synchronization

GO:lack of synchronization

Linda Hamilton
Release: 2024-11-30 01:10:11
Original
496 people have browsed it

GO:lack of synchronization

var a string
var done bool

func setup() {
    a = "hello, world"
    done = true
}

func doprint() {
    if !done {
        once.Do(setup)
    }
    print(a)
}

func twoprint() {
    go doprint()
    go doprint()
}
Copy after login

Code Analysis

Variables:

  • a and b are global variables of type int, shared by all goroutines.

Functions:

  • f():
    • Writes to a and b sequentially (a = 1 and b = 2).
  • g():
  • Reads and prints b followed by a.

Concurrency in main():

  • The function f() is executed as a separate goroutine using go f().
  • The function g() is executed directly in the main goroutine.

Potential Issues:

  • The goroutine running f() and the main goroutine executing g() run concurrently.
  • The writes to a and b in f() may not complete before g() reads and prints the values of a and b.
  • This introduces a data race, where concurrent access (writes in f() and reads in g()) occurs on shared memory (a and b) without synchronization.

Possible Outcomes
Due to the lack of synchronization, the program's output is non-deterministic. Here are the possible scenarios:

Case 1: g() executes before f() modifies a and b:

  • Initial values of a and b are 0 (default for uninitialized int in Go).
0
0

Copy after login

or

CASE 2: If b = 2 is completed before g() but a = 1 is not, the output could be:

2
0
Copy after login

Key Observations
Data Race: The concurrent access to a and b without synchronization introduces a data race. This makes the program's behavior undefined and unpredictable

Fixing the Code

  1. Using a sync.WaitGroup: Ensure f() completes before g() executes
var a, b int
var wg sync.WaitGroup

func f() {
    a = 1
    b = 2
    wg.Done()
}

func g() {
    print(b)
    print(a)
}

func main() {
    wg.Add(1)
    go f()
    wg.Wait()
    g()
}

Copy after login
  1. Using Channels: Signal when f() is done:
var a, b int

func f(done chan bool) {
    a = 1
    b = 2
    done <- true
}

func g() {
    print(b)
    print(a)
}

func main() {
    done := make(chan bool)
    go f(done)
    <-done
    g()
}

Copy after login

Here, g() waits until f() sends a signal over the done channel.

The above is the detailed content of GO:lack of synchronization. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
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
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template