如何修复golang的比赛条件?

如何修复golang的比赛条件?,go,race-condition,goroutine,Go,Race Condition,Goroutine,我正在尝试修复golang中的竞争条件,我使用了waitgroup,正如您所看到的,我添加了两个waitgroup,并调用Done()。但仍然没有导出输出 package main import ( "fmt" "time" "sync" ) var counter int = 0 func task(m string, n int, wg *sync.WaitGroup) { defer wg.

我正在尝试修复golang中的竞争条件,我使用了waitgroup,正如您所看到的,我添加了两个waitgroup,并调用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 2
first 1
first 1
second 2
first 1
second 2
second 2
...

对于任何正在寻找如何在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()
}
主程序包
进口(
“fmt”
“时间”
“同步”
)
变量计数器int=0
func任务(m字符串,n int,wg*sync.WaitGroup,mux*sync.Mutex){
推迟工作组完成()
对于i:=0;i<100;i++{
mux.Lock()
//您的共享资源
计数器=n
时间。睡眠(100000)
fmt.Println(m,计数器)
计数器=0
//共享资源的结束
mux.Unlock()
}
}
func main(){
var wg sync.WaitGroup
var mux sync.Mutex
工作组.添加(1)
go任务(“第一个”、第1个、第2个、第2个和第2个、第3个和第3个)
工作组.添加(1)
go任务(“第二个”、第二个、第二个、第二个和第二个、第三个和第三个任务)
wg.Wait()
}

等待组用于等待goroutines,它不会神奇地同步数据访问。从多个goroutine访问同一变量时,需要同步。最简单的是互斥。但在您的示例中,只有在睡眠调用期间保持互斥时,这才有效。这是正确的用法,但毫无意义:您现在正在序列化两个goroutine的执行。为什么还要将它们作为goroutine?@Marc我认为如果两个go例程在没有竞争条件的情况下尝试访问相同的资源,这是一个解决方案。当然,不会有竞争条件,但这是因为您的第二个goroutine正在等待第一个goroutine完成。我建议您参观一下go,它介绍了一些有用的同步功能。这里根本没有理由使用共享变量,因为您可以在打印
n
时获得完全相同的输出。您所做的唯一一件事就是将
第一个
第二个
的顺序设置为非确定性。如果这是你想要的,那就太好了,但你只需要互斥就可以了。@JimB原因是我想学习golang中的同步是如何工作的。谢谢,正如Marc所指出的,互斥是这里的答案。
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()
}