Multithreading 自同步Goroutines最终会导致死锁

Multithreading 自同步Goroutines最终会导致死锁,multithreading,go,synchronization,deadlock,Multithreading,Go,Synchronization,Deadlock,我有一个压力测试问题,我想用Go中的简单同步来解决。到目前为止,我试图找到关于Go中同步的特定用例的文档,但没有找到任何合适的文档 具体来说: 我必须完成一个任务,在这个任务中,我必须在主例程中启动大量线程(在本例中仅用两个线程进行说明)。所有已启动的工作人员都应该以无序的方式自行准备一些初始化操作。直到它们到达一个小的命令序列,我希望所有goroutine一次执行这些命令,这就是为什么我希望goroutine彼此自同步的原因。对于我的任务来说,通过主例程(实例化所有其他goroutine)的延

我有一个压力测试问题,我想用Go中的简单同步来解决。到目前为止,我试图找到关于Go中同步的特定用例的文档,但没有找到任何合适的文档

具体来说: 我必须完成一个任务,在这个任务中,我必须在主例程中启动大量线程(在本例中仅用两个线程进行说明)。所有已启动的工作人员都应该以无序的方式自行准备一些初始化操作。直到它们到达一个小的命令序列,我希望所有goroutine一次执行这些命令,这就是为什么我希望goroutine彼此自同步的原因。对于我的任务来说,通过主例程(实例化所有其他goroutine)的延迟不会影响worker执行的真正并行性(在注释中的标签#maximum parallel)是非常重要的。为此,我使用主例程中正在运行的goroutine的数量初始化等待组,并将其传递给所有例程,以便它们可以相互同步工作流

代码类似于此示例:

import sync

func worker_action(wait_group *sync.WaitGroup) {
    // ...
    // initialization
    // ...

    defer wait_group.Done() 
    wait_group.Wait() // #label: wait

    // sequence of maximum parallel instructions // #label: maximum parallel

    // ...
}

func main() {
    var numThreads int = 2 // the number of threads shall be much higher for the actual stress test

    var wait_group sync.WaitGroup
    wait_group.Add(numThreads)
    for i := 0; i < numThreads; i++ {
        go worker_action(&wait_group)
    }

    // ...
}
导入同步
func worker_操作(等待组*sync.WaitGroup){
// ...
//初始化
// ...
延迟等待组。完成()
wait_组。wait()/#标签:wait
//最大并行指令序列/#标签:最大并行
// ...
}
func main(){
var numThreads int=2//实际应力测试的螺纹数应高得多
var wait_group sync.WaitGroup
wait_group.Add(numThreads)
对于i:=0;i
不幸的是,当所有goroutine到达Wait指令(注释中标有#Wait)时,我的安装程序就陷入了死锁。对于我从主例程开始的任何数量的线程都是如此(即使是两个线程也会在短时间内陷入死锁)

在我看来,死锁不应该发生,因为在wait指令之前,每个goroutine都在同一个wait组上执行done函数

我是否对等待小组的工作方式有错误的理解?例如,除了主例程之外,是否不允许在goroutine内部执行wait函数?或者有人能给我一个提示,说明我还遗漏了什么

事先非常感谢

编辑:


非常感谢@tkausl。确实是不必要的“推迟”造成了问题。我不知道自己怎么看不见。再次感谢@tkausl。该问题通过从行中删除不必要的“defer”指令得到解决,该指令旨在让辅助进程goroutines增加完成的线程数


例如,“延迟等待组.Done()”->“等待组.Done()”

您的代码中有几个问题。首先是形式。惯用的Go应该使用camelCase
wg
是WaitGroup的更好名称

但更重要的是在代码等待的地方使用。不是在你的社交圈里。它应该在主函数内等待:

func workerAction(wg *sync.WaitGroup) {
    // ...
    // initialization
    // ...

    defer wg.Done() 
    // wg.Wait() // #label: wait

    // sequence of maximum parallel instructions // #label: maximum parallel

    // ...
}

func main() {
    var numThreads int = 2 // the number of threads shall be much higher for the actual stress test

    var wg sync.WaitGroup
    wg.Add(numThreads)
    for i := 0; i < numThreads; i++ {
        go workerAction(&wg)
    }
    wg.Wait() // you need to wait here

    // ...
}
func-workerAction(wg*sync.WaitGroup){
// ...
//初始化
// ...
推迟工作组完成()
//wg.Wait()/#标签:Wait
//最大并行指令序列/#标签:最大并行
// ...
}
func main(){
var numThreads int=2//实际应力测试的螺纹数应高得多
var wg sync.WaitGroup
添加(numThreads)
对于i:=0;i
在我看来,死锁不应该发生,因为在wait指令之前,每个goroutine都会在同一等待组上执行done函数。
它不会发生死锁。为什么<代码>推迟< /代码>?您可能需要考虑Syc.COND.COMPATE来替换WAITGROUP。