V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Morriaty
V2EX  ›  Go 编程语言

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

  •  
  •   Morriaty · 2017-06-23 15:31:12 +08:00 · 1265 次点击
    这是一个创建于 2714 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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,但似乎依旧阻塞了?

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

    不然传参数的时候就是复制了,文档里说了不能复制
    reus
        5
    reus  
       2017-06-23 16:10:41 +08:00   ❤️ 1
    用 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
        6
    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
        7
    Morriaty  
    OP
       2017-06-23 16:35:55 +08:00
    @reus
    @tonyluj
    谢谢 没写多久 golang 都不知道有这个工具
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3450 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 00:42 · PVG 08:42 · LAX 16:42 · JFK 19:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.