gpt4 book ai didi

go - 如何在单个程序中使用多个 sync.WaitGroup

转载 作者:行者123 更新时间:2023-12-01 22:40:41 24 4
gpt4 key购买 nike

在我的 Go 程序中,我为每个部门启动了多个工作组。
我想在退出程序之前等待每个部门的工作人员完成

我不能使用单个 WaitGroups,因为在实际场景中,我可能必须结束任何特定部门并且只需要等待。

这是代码的简化版本,但它会出现一条消息

panic: runtime error: invalid memory address or nil pointer dereference


package main

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

var wgMap map[string]*sync.WaitGroup

func deptWorker(dName string, id int) {
defer wgMap[dName].Done()
fmt.Printf("Department %s : Worker %d starting\n", dName, id)
time.Sleep(time.Second)
fmt.Printf("Department %s : Worker %d done\n", dName, id)
}

func department(dName string) {
var wg sync.WaitGroup
for i := 1; i <= 3; i++ {
wg.Add(1)
go deptWorker(dName, i)
}
wgMap[dName] = &wg
}

func main() {
go department("medical")
go department("electronics")

wgMap["medical"].Wait()
wgMap["electronics"].Wait()
}

最佳答案

两个修复零 panic 你只需要使用

var wgMap = map[string]*sync.WaitGroup{} 

它将初始化 map 。但是,在我看来,最好在这里创建一个新的抽象,我们将其命名为“WaitMap”。

可以这样实现:
package main

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

type WaitMapObject struct {
wg map[string]int
mu sync.Mutex
cond sync.Cond
}

func WaitMap() *WaitMapObject {
m := &WaitMapObject{}
m.wg = make(map[string]int)
m.cond.L = &m.mu
return m
}

func (m *WaitMapObject) Wait(name string) {
m.mu.Lock()
for m.wg[name] != 0 {
m.cond.Wait()
}
m.mu.Unlock()
}

func (m *WaitMapObject) Done(name string) {
m.mu.Lock()
no := m.wg[name] - 1
if no < 0 {
panic("")
}
m.wg[name] = no
m.mu.Unlock()
m.cond.Broadcast()
}

func (m *WaitMapObject) Add(name string, no int) {
m.mu.Lock()
m.wg[name] = m.wg[name] + no
m.mu.Unlock()
}

func deptWorker(dName string, id int, wm *WaitMapObject) {
defer wm.Done(dName)
fmt.Printf("Department %s : Worker %d starting\n", dName, id)
time.Sleep(time.Second)
fmt.Printf("Department %s : Worker %d done\n", dName, id)
}

func department(dName string, wm *WaitMapObject) {
for i := 1; i <= 3; i++ {
wm.Add(dName,1)
go deptWorker(dName, i, wm)
}
wm.Done(dName)
}

func main() {
wm := WaitMap()

wm.Add("mediacal",1)
go department("medical", wm)

wm.Add("electronics",1)
go department("electronics", wm)

wm.Wait("medical")
wm.Wait("electronics")
}

关于go - 如何在单个程序中使用多个 sync.WaitGroup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60137755/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com