首页 >后端开发 >Golang >GO:缺乏同步

GO:缺乏同步

Linda Hamilton
Linda Hamilton原创
2024-11-30 01:10:11519浏览

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()
}

代码分析

变量:

  • a 和 b 是 int 类型的全局变量,为所有 goroutine 共享。

功能:

  • f():
    • 顺序写入 a 和 b(a = 1 且 b = 2)。
  • g():
  • 读取并打印 b,然后打印 a。

main() 中的并发:

  • 函数 f() 使用 go f() 作为单独的 goroutine 执行。
  • 函数 g() 直接在主 goroutine 中执行。

潜在问题:

  • 运行 f() 的 goroutine 和执行 g() 的主 goroutine 并发运行。
  • 在 g() 读取并打印 a 和 b 的值之前,f() 中对 a 和 b 的写入可能无法完成。
  • 这引入了数据竞争,其中并发访问(在 f() 中写入并在 g() 中读取)发生在共享内存(a 和 b)上,而无需同步。

可能的结果
由于缺乏同步,程序的输出是不确定的。以下是可能的情况:

情况 1:g() 在 f() 修改 a 和 b 之前执行:

  • a 和 b 的初始值为 0(Go 中未初始化 int 的默认值)。
0
0

情况 2:如果 b = 2 在 g() 之前完成,但 a = 1 未完成,则输出可能为:

2
0

主要观察结果
数据竞争:在不同步的情况下对 a 和 b 进行并发访问会引入数据竞争。这使得程序的行为变得不确定且不可预测

修复代码

  1. 使用sync.WaitGroup: 确保 f() 在 g() 执行之前完成
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()
}

  1. 使用频道: 当 f() 完成时发出信号:
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()
}

这里,g() 等待,直到 f() 通过完成的通道发送信号。

以上是GO:缺乏同步的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn