登录
首页 >  Golang >  Go问答

Goroutine 执行后陷入停滞

来源:stackoverflow

时间:2024-02-22 09:54:25 256浏览 收藏

小伙伴们有没有觉得学习Golang很有意思?有意思就对了!今天就给大家带来《Goroutine 执行后陷入停滞》,以下内容将会涉及到,若是在学习中对其中部分知识点有疑问,或许看了本文就能帮到你!

问题内容

我想要有限数量的 goroutine 进行一些计算(funcworker(),它进行一些计算并将结果放入通道中)。还有另一个频道,为我的工人提供“工作”。结果我可以看到所有作业都计算正确,但计算执行后卡住了。

package main
import (
    "bufio"
    "fmt"
    "os"
    "net/http"
    "io/ioutil"
    "strings"
    "time"
)


func worker(id int, urls <- chan string, results chan<- int) {
    var data string
    for url := range urls {
        fmt.println("worker", id, "started  job", url)
        if (strings.hasprefix(url, "http") ||  strings.hasprefix(url, "https")) {
            resp, err := http.get(url)
            if err != nil {
                fmt.println(err)
            }
            defer  resp.body.close()
            body, err := ioutil.readall(resp.body)
            if err != nil {
                fmt.println(err)
            }
            data = string(body)
        } else {
            body, err := ioutil.readfile(url)
            if err != nil {
                fmt.println(err)
            }
            data = string(body)
        }
        number := strings.count(data, "go")
        fmt.println("worker", id, "finished  job", url, "number of go is", number)
        results <- number
    }
    return
}

func main() {
    final_result := 0
    maxnbconcurrentgoroutines := 5
    numjobs := 0
    urls := make(chan string)
    results := make(chan int)

    scanner := bufio.newscanner(os.stdin)
    start := time.now()
    for w := 1; w <= maxnbconcurrentgoroutines; w++ {
        go worker(w, urls, results)
    }
    for scanner.scan() {
        url := (scanner.text())
        urls <- url
        numjobs += 1
    }
    close(urls)
    for num := range results {
        final_result += num
    }
    t := time.now()
    elapsed := t.sub(start)
    for i := 1; i <= numjobs; i++ {
        one_result := <- results
        final_result += one_result
    }
    fmt.println("number = ", final_result)
    fmt.println("time = ", elapsed)
    if err := scanner.err(); err != nil {
        fmt.fprintln(os.stderr, "error:", err)
        os.exit(1)
    }
}

我尝试使用 https://gobyexample.com/worker-pools 从结果通道中提取所有值,但没有成功。我该怎么做才能把它拆开并走得更远。以下是如何运行它的示例:

echo -e 'https://golang.org\n/etc/passwd\nhttps://golang.org\nhttps://golang.org' | go run 1.go

解决方案


您的程序不会返回,因为它正在等待结果通道的关闭状态。

https://gobyexample.com/worker-pools 中,获取结果的循环有所不同:

for a := 1; a <= numJobs; a++ {
    <-results
}

如果您想使用 for num := range results 您需要 close(results) 并确定何时调用它。

您可以在 https://gobyexample.com/waitgroups 查看使用 waitgroup 的另一个示例

到这里,我们也就讲完了《Goroutine 执行后陷入停滞》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>