首页 文章

Go Channel并使用指针变量进行例程所有goroutine都处于睡眠状态 - 死锁

提问于
浏览
0

我花了一个晚上看看如何解决这个错误,但我还没有成功 . 当我运行程序时,我有以下错误:“所有goroutines都睡着了 - 死锁!” . 我理解这是因为主程序在例程有可能完成任务之前退出,我认为使用sync.WaitGroup会有所帮助但不是真的:/

我想设置一些例程和使用通道来发送网址,以检查http状态代码 . 我想限制对网站的并发调用次数 . 我跟着例子用字符串而不是struct做同样的事情并且它起作用了 .

任何帮助将不胜感激:)

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\n", 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\n", time.Now())
}

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

2 回答

  • 1

    首先,你有太多的电话 wg.Add() . 你为每个正在运行的goroutine召唤一次 . 见http://golang.org/pkg/sync/#WaitGroup . 其次,你没有't close the channel after you were done writing to it. Here'是你的代码的修改版本:

    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\n", 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\n", time.Now())
    }
    

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

  • 3

    你忘了关闭 Channels ,你的等待组太长了 . 这对我有用:https://play.golang.org/p/yasIzaCbmQ

相关问题