【问题标题】:how to fix race condition in golang?如何修复golang中的竞争条件?
【发布时间】:2023-04-06 13:27:01
【问题描述】:

我正在尝试修复 golang 中的竞争条件,我使用了等待组,正如您所见,我添加了两个等待组并调用了 Done()。但仍然没有预期的输出。

package main

import (
    "fmt"
    "time"
    "sync"
)

var counter int = 0

func task(m string, n int,  wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0 ; i < 100 ; i++ {
        counter = n
        time.Sleep(100000)
        fmt.Println(m, counter)
        counter = 0
    }
}

func main() {
    var wg sync.WaitGroup
    wg.Add(1)
    go task("first", 1, &wg) // i want "first" task should get always 1
    wg.Add(1)
    go task("second", 2, &wg) // // i want "second" task should get always 2
    wg.Wait()
}

以上程序输出

second 1
first 1
first 1
second 1
first 2
second 2
second 2
...

预期输出

second 2
first 1
first 1
second 2
first 1
second 2
second 2
...

【问题讨论】:

  • 一个等待组用于等待 goroutines,它不会神奇地同步数据访问。当从多个 goroutine 访问同一个变量时,您需要同步。最简单的是互斥锁。但在您的示例中,这只有在您在睡眠呼叫期间还持有互斥锁时才有效。

标签: go race-condition goroutine


【解决方案1】:

致任何正在寻找如何在 golang 中使用 sync.Mutex 进行同步的人。这可能会有所帮助。如果此解决方案不正确,请发表评论或回复。

package main

import (
    "fmt"
    "time"
    "sync"
)

var counter int = 0

func task(m string, n int,  wg *sync.WaitGroup, mux *sync.Mutex) {
    
    defer wg.Done()
    for i := 0 ; i < 100 ; i++ {
        mux.Lock()
        //your shared resource
        counter = n
        time.Sleep(100000)
        fmt.Println(m, counter)
        counter = 0
        //end of your shared resource
        mux.Unlock()
    }
}

func main() {
    var wg sync.WaitGroup
    var mux sync.Mutex
    wg.Add(1)
    go task("first", 1, &wg, &mux)
    wg.Add(1)
    go task("second", 2, &wg, &mux)
    wg.Wait()
}

【讨论】:

  • 这是正确的用法,但毫无意义:您现在正在序列化您的两个 goroutine 的执行。为什么还要将它们用作 goroutine?
  • @Marc 我认为如果两个 goroutine 尝试在没有竞争条件的情况下访问相同的资源,这就是解决方案。
  • 当然,不会有竞争条件,但那是因为你的第二个 goroutine 只是在等待第一个 goroutine 完成。我推荐你去看看 go,它涵盖了一些有用的同步功能。
  • 这里根本没有共享变量的理由,因为您可以获得完全相同的输出打印n。您唯一要做的就是使firstsecond 的顺序不确定。如果这就是你想要的,那就太好了,但你只需要互斥体。
  • @JimB 原因是我想了解 golang 中的同步是如何工作的。谢谢,正如 Marc 指出的那样,mutex 是这里的答案。
猜你喜欢
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多