代码如下,目的是为了同时下载很多台交换机的配置,sws 里有多组业务的交换机,每个业务的每一台配置的下载我都要同时进行,下面的代码是我拍脑袋写下来的,目的达到了,但怎么看都不顺眼,我的 go 水平目前实在有限,求助各位指导一下。
func (s *swbka) downloadSwitchCfg(sws map[string]mulparam) {
wgp := sync.WaitGroup{}
wgp.Add(len(sws))
for secN, mulP := range sws {
go func(secName string, mulP mulparam) {
if _, err := os.Stat(secName); os.IsNotExist(err) {
err := os.Mkdir(secName, 0644)
if err != nil {
logrus.Fatal(err)
}
}
wg := sync.WaitGroup{}
wg.Add(len(mulP.profiles))
for _, profile := range mulP.profiles {
go func(sn string, pf param) {
err := s.downloadFile(sn, pf)
if err != nil {
logrus.Errorln(err)
}
wg.Done()
}(secName, profile)
}
wg.Wait()
wgp.Done()
}(secN, mulP)
}
wgp.Wait()
}
1
GGGG430 2020-09-09 23:02:30 +08:00 1
外层的 WaitGroup 可以理解为进程等待, 里层的 WaitGroup+go func 感觉没必要;
或者这样简化一下 ``` func (s *swbka) downloadSwitchCfg(sws map[string]mulparam) { wgp := sync.WaitGroup{} for secN, mulP := range sws { if _, err := os.Stat(secName); os.IsNotExist(err) { if err := os.Mkdir(secName, 0644); err != nil { logrus.Fatal(err) continue } } wgp.Add(1) for _, profile := range mulP.profiles { go func(sn string, pf param, wg *sync.WaitGroup) { defer func() { wg.Done() }() err := s.downloadFile(sn, pf) if err != nil { logrus.Errorln(err) } }(secName, profile, &wgp) } } wgp.Wait() } ``` |
2
Aumujun OP @GGGG430 你这个看起来确实比我原来那个强太多了,发帖之后思考了一下,改成了下面这样
```golang func downloadFunc(s *swbka, wg *sync.WaitGroup, secName string, mulP mulparam) { if _, err := os.Stat(secName); os.IsNotExist(err) { err := os.Mkdir(secName, 0644) if err != nil { logrus.Fatal(err) } } for _, profile := range mulP.profiles { go func(sn string, pf param) { // err := s.downloadFile(sn, pf) err := s.downloadFileMock(sn, pf) wg.Done() if err != nil { logrus.Errorln(err) } }(secName, profile) } } func (s *swbka) downloadSwitchCfg(sws map[string]mulparam) { wg := sync.WaitGroup{} // wg.Add(len(sws)) for secN, mulP := range sws { wg.Add(len(mulP.profiles)) go downloadFunc(s, &wg, secN, mulP) } wg.Wait() } ``` 不过看了你的回复后,感觉获得了新的启示 |
3
iwdmb 2020-09-09 23:24:29 +08:00
```
func (s *swbka) downloadSwitchCfg(sws map[string]mulparam) { wgp := sync.WaitGroup{} wgp.Add(len(sws)) for secName, mulP := range sws { go func(secName string, mulP mulparam) { if _, err := os.Stat(secName); os.IsNotExist(err) { err := os.Mkdir(secName, 0644) if err != nil { logrus.Fatal(err) } } wg := sync.WaitGroup{} wg.Add(len(mulP.profiles)) for _, profile := range mulP.profiles { go func(sn string, pf param) { err := s.downloadFile(sn, pf) if err != nil { logrus.Errorln(err) } wg.Done() }(secName, profile) } wg.Wait() wgp.Done() }(secN, mulP) } wgp.Wait() } ``` |
4
iwdmb 2020-09-09 23:26:19 +08:00
|
5
iwdmb 2020-09-09 23:27:14 +08:00 1
|
6
Aumujun OP |
7
Aumujun OP 非常感谢,优化成这种程度我已经满足了,感谢两位大哥的指点
|
8
heimeil 2020-09-10 02:04:52 +08:00 1
|
9
zarte 2020-09-10 09:58:32 +08:00 1
我觉得可以加下限制协程数。
|
10
situs 2020-09-10 12:18:47 +08:00 1
你的 Done()应该用 defer,你现在是顺序执行的,如果上面 err 了,你这协程 done 不了了
|
11
dafsic 2020-09-10 14:58:06 +08:00 1
你这个是多协程处理同样的任务的,没有最多协程的数的限制。https://github.com/90634/gotaskengine,我线上环境用的,多协程处理多任务的。
|