登录
首页 >  Golang >  Go问答

所有任务为什么都被集中在一个 goroutine 中执行?

来源:stackoverflow

时间:2024-03-15 10:09:29 162浏览 收藏

从现在开始,努力学习吧!本文《所有任务为什么都被集中在一个 goroutine 中执行?》主要讲解了等等相关知识点,我会在golang学习网中持续更新相关的系列文章,欢迎大家关注并积极留言建议。下面就先一起来看一下本篇正文内容吧,希望能帮到你!

问题内容

我正在实施管道风扇粉丝出局图案。 buut我不明白为什么代码会这样起作用,请向我解释。

我的第一个代码。所有任务都符合第一个goroutine: https://go.dev/play/p/x6dqeuj86cz

func main() {
    var rdnums []int
    for i := 0; i < 1000; i++ {
        rdnums = append(rdnums, i)
    }

    pl := generatepipeline(rdnums)
    c1 := fanout(pl, "1")
    c2 := fanout(pl, "2")
    c3 := fanout(pl, "3")
    c4 := fanout(pl, "4")

    c := fanin(c1, c2, c3, c4)
    sum := 0
    for i := range c {
        sum += i
    }

    fmt.println(sum)
}

func generatepipeline(arrnums []int) <-chan int {
    pl := make(chan int, 100)
    go func() {
        for _, n := range arrnums {
            pl <- n
        }

        close(pl)
    }()

    return pl
}

func fanout(in <-chan int, name string) <-chan int {
    out := make(chan int)
    go func() {
        for v := range in {
            fmt.printf("push square of %d to channel %s \n", v*v, name)
            out <- v * v

        }

        close(out)
    }()

    return out
}

func fanin(inputchan ...<-chan int) <-chan int {
    in := make(chan int)

    go func() {
        for _, c := range inputchan {
            for v := range c {
                in <- v
            }
        }

        close(in)
    }()

    return in
}

我的第二个代码。每个goroutine上的任务大致均匀: https://go.dev/play/p/7vg8x6kgurp

func main() {
    var rdNums []int
    for i := 0; i < 1000; i++ {
        rdNums = append(rdNums, i)
    }

    pl := createQueue(rdNums)
    for i := 0; i < 5; i++ {
        go process(pl, fmt.Sprintf("worker%d", i))
    }

    time.Sleep(1 * time.Minute)
}

func createQueue(arrNums []int) <-chan int {
    pl := make(chan int)
    go func() {
        for _, n := range arrNums {
            pl <- n
        }

        close(pl)
    }()

    return pl
}

func process(in <-chan int, name string) {
    count := 0
    go func() {
        for v := range in {
            fmt.Printf("Push square of %d to channel %s \n", v*v, name)
            count++

        }

        fmt.Printf("Process %s success, total number reiceive %d\n", name, count)
    }()
}

我真的很想明白为什么会有这种差异?谢谢。


正确答案


您的第一个扇入实现已损坏。

go func() {
        for _, c := range inputChan {
            for v := range c {
                in <- v
            }
        }

上面的 goroutine 将获取第一个 inputchan ,并从中读取直到该通道关闭,这意味着直到生成器完成。有四个 goroutine 向四个通道发送数据,因此当第一个 inputchan 正在处理时,所有其他协程将等待发送到各自的通道。一旦第一个 inputchan 完成并关闭,其余三个 goroutine 就可以发送它们的输入,并且程序终止。

可以通过将从输入通道读取数据的内循环移动到单独的 goroutine(每个通道一个)并将数据发送到公共输出通道来解决此问题。

今天关于《所有任务为什么都被集中在一个 goroutine 中执行?》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

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