使用有缓存的 chan,但 sync.WaitGroup 在 wait()时死住了

2017-06-23 15:31:12 +08:00
 Morriaty
func fetch(url string, channel chan string, wg sync.WaitGroup) {
	defer wg.Done()
	resp, err := http.Get(url)
	if (err != nil) || (resp.StatusCode != http.StatusOK) {
		temp := fmt.Sprintf("Cannot fetch %s", url)
		channel <- temp
		fmt.Println("put one")
	}
}

func preFetchAd(ad *Ad) error {
	var wg sync.WaitGroup
	count := 0
	count = count + len(ad.Urls)
	for _, urls := range ad.Urls2 {
		count = count + len(urls)
	}
	c := make(chan string, count)
	//fmt.Println(count)
	errs := []string{}
	for _, url := range ad.Urls {
		wg.Add(1)
		go fetch(url.L, c, wg)
	}
	for _, urls := range ad.Urls2 {
		for _, url := range urls {
			wg.Add(1)
			go fetch(url.L, c, wg)
		}
	}

	wg.Wait()
	close(c)

	for err := range c {
		errs = append(errs, err)
	}

	if len(errs) == 0 {
		return nil
	}
	e := strings.Join(errs, "\n")
	return errors.New(e)
}

我先预算了个数,创建了足够缓存的 chan,但似乎依旧阻塞了?

1257 次点击
所在节点    Go 编程语言
7 条回复
orderc
2017-06-23 15:37:29 +08:00
// wg 要传指针
func fetch(url string, channel chan string, wg sync.WaitGroup)
spice630
2017-06-23 15:38:08 +08:00
发个最小可重现代码,不然别人怎么帮你调?
nybux
2017-06-23 16:05:16 +08:00
1.一楼 @orderc 说的不错
2.另外 resp.body.Close 不要忘记
3.这种问题可以通过加写日志来定位
reus
2017-06-23 16:08:48 +08:00
wg := new(sync.WaitGroup)

不然传参数的时候就是复制了,文档里说了不能复制
reus
2017-06-23 16:10:41 +08:00
用 go tool vet 也能发现错误
例如下面的代码

package main

import "sync"

func main() {
var wg sync.WaitGroup
foo(wg)
}

func foo(wg sync.WaitGroup) {
}


执行

go tool vet a.go

输出

a.go:7: call of foo copies lock value: sync.WaitGroup contains sync.noCopy
a.go:10: foo passes lock by value: sync.WaitGroup contains sync.noCopy
tonyluj
2017-06-23 16:13:29 +08:00
善用 go vet,可以提前发现这些问题
main.go:5: fetch passes lock by value: sync.WaitGroup contains sync.noCopy
Morriaty
2017-06-23 16:35:55 +08:00
@reus
@tonyluj
谢谢 没写多久 golang 都不知道有这个工具

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/370595

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX