doujingya1166 2014-12-15 23:12
浏览 47
已采纳

使用指针变量转到Channel和go例程,所有goroutine都处于睡眠状态-死锁

I spend my evening looking at how to fix this error but I haven't succeeded. When I run the program I have the following error : "all goroutines are asleep - deadlock!". I understand this is because the main program is exited before the routine has the possibility to do its tasks and I thought using sync.WaitGroup would help but not really :/

I want to set a number of routine and use channels to send urls in order to check http status code. I want to limit the number of concurrency call to a website. I've followed examples doing the same thing with string instead of struct and it worked.

Any help would be well appreciated :)

package main

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

const (
    numPollers = 2                // number of Poller goroutines to launch
)

var urls = []string{
    "http://www.google.com/",
    "http://golang.org/",
    "http://blog.golang.org/",
    "http://golangtutorials.blogspot.fr",
    "https://gobyexample.com/",
}

// Resource represents an HTTP URL to be polled by this program.
type Resource struct {
    url      string
}

func Poller(in <-chan *Resource, wg *sync.WaitGroup) {
    //defer wg.Done()
    for r := range in {
        fmt.Printf("Finished: %v - %v
", r.url, time.Now())
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    pending := make(chan *Resource)

    wg.Add(len(urls))

    go Poller(pending, &wg)

    go func() {
        for _, url := range urls {
            wg.Add(1)
            fmt.Println("SENT > Pending url " + url)
            pending <- &Resource{url: url}
        }
    }()

    wg.Wait()

    fmt.Printf("Finished all goroutines: %v
", time.Now())
}

https://play.golang.org/p/B-HSiDo2Qg

  • 写回答

2条回答 默认 最新

  • dp152153 2014-12-15 23:30
    关注

    First, you have too many calls to wg.Add(). You call that once for each goroutine you're running. See http://golang.org/pkg/sync/#WaitGroup. Second, you didn't close the channel after you were done writing to it. Here's a modified version of your code:

    package main
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    const (
        numPollers = 2                // number of Poller goroutines to launch
    )
    
    var urls = []string{
        "http://www.google.com/",
        "http://golang.org/",
        "http://blog.golang.org/",
        "http://golangtutorials.blogspot.fr",
        "https://gobyexample.com/",
    }
    
    // Resource represents an HTTP URL to be polled by this program.
    type Resource struct {
        url      string
    }
    
    func Poller(in <-chan *Resource, wg *sync.WaitGroup) {
        defer wg.Done()
        for r := range in {
            fmt.Printf("Finished: %v - %v
    ", r.url, time.Now())
        }
    }
    
    func main() {
        var wg sync.WaitGroup
        pending := make(chan *Resource)
    
        wg.Add(2)
    
        go Poller(pending, &wg)
    
        go func() {
            defer close(pending)
            defer wg.Done()
            for _, url := range urls {
                fmt.Println("SENT > Pending url " + url)
                pending <- &Resource{url: url}
            }
        }()
    
        wg.Wait()
    
        fmt.Printf("Finished all goroutines: %v
    ", time.Now())
    }
    

    and https://play.golang.org/p/ucUlZEZMZM

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 在获取boss直聘的聊天的时候只能获取到前40条聊天数据
  • ¥20 关于URL获取的参数,无法执行二选一查询
  • ¥15 液位控制,当液位超过高限时常开触点59闭合,直到液位低于低限时,断开
  • ¥15 marlin编译错误,如何解决?
  • ¥15 有偿四位数,节约算法和扫描算法
  • ¥15 VUE项目怎么运行,系统打不开
  • ¥50 pointpillars等目标检测算法怎么融合注意力机制
  • ¥20 Vs code Mac系统 PHP Debug调试环境配置
  • ¥60 大一项目课,微信小程序
  • ¥15 求视频摘要youtube和ovp数据集