{ "@context": "https://schema.org", "@type": "Article", "headline": "进行通道范围的常规操作", "datePublished": "2024-04-17T18:06:37", "dateModified": "2024-04-17T18:06:37", "description": "各位小伙伴们,大家好呀!看看今天我又给各位带来了什么文章?本文标题是《进行通道范围的常规操作》,很明显是关于Golang的文章哈哈哈,其中内容主要会涉及到等等,如果能帮到你,觉得很不错的话,欢迎各位多多点评和分享!问题内容我在 golang 工作了很长时间。但尽管我知道问题的解决方案,但我仍然面临这个问题。但一直不明白为什么会这样。例如,如果我的入站和出站通道的管道情况如下:package mainimport ( fmt)func main() { for n := range sq(s", "publisher": { "@type": "Organization", "name": "Golang学习网", "url": "https://m.17golang.com" }, "mainEntityOfPage": { "@type": "WebPage", "@id": "https://m.17golang.com/article/124741.html" } }
登录
首页 >  Golang >  Go问答

进行通道范围的常规操作

来源:stackoverflow

时间:2024-04-17 18:06:37 126浏览 收藏

各位小伙伴们,大家好呀!看看今天我又给各位带来了什么文章?本文标题《进行通道范围的常规操作》,很明显是关于Golang的文章哈哈哈,其中内容主要会涉及到等等,如果能帮到你,觉得很不错的话,欢迎各位多多点评和分享!

问题内容

我在 golang 工作了很长时间。但尽管我知道问题的解决方案,但我仍然面临这个问题。但一直不明白为什么会这样。

例如,如果我的入站和出站通道的管道情况如下:

package main

import (
    "fmt"
)

func main() {
    for n := range sq(sq(gen(3, 4))) {
        fmt.println(n)
    }
    fmt.println("process completed")
}

func gen(nums ...int) <-chan int {
    out := make(chan int)
    go func() {
        for _, n := range nums {
            out <- n
        }
        close(out)
    }()
    return out
}

func sq(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        for n := range in {
            out <- n * n
        }
        close(out)
    }()
    return out
}

它不会给我带来僵局。但是如果我删除出站代码中的 go 例程,如下所示:

func sq(in <-chan int) <-chan int {
    out := make(chan int)
    for n := range in {
        out <- n * n
    }
    close(out)
    return out
}

我收到死锁错误。为什么使用 range 而不使用 go 例程来循环通道会导致死锁。


解决方案


这种情况是由于sq函数的输出通道没有被缓冲造成的。因此 sq 正在等待下一个函数从输出中读取,但如果 sq 不是异步的,则不会发生(Playground link):

package main

import (
    "fmt"
    "sync"
)

var wg sync.WaitGroup

func main() {
    numsCh := gen(3, 4)
    sqCh := sq(numsCh) // if there is no sq in body - we are locked here until input channel will be closed
    result := sq(sqCh) // but if output channel is not buffered, so `sq` is locked, until next function will read from output channel

    for n := range result {
        fmt.Println(n)
    }
    fmt.Println("Process completed")
}

func gen(nums ...int) <-chan int {
    out := make(chan int)
    go func() {
        for _, n := range nums {
            out <- n
        }
        close(out)
    }()
    return out
}

func sq(in <-chan int) <-chan int {
    out := make(chan int, 100)
    for n := range in {
        out <- n * n
    }
    close(out)
    return out
}

理论要掌握,实操不能落!以上关于《进行通道范围的常规操作》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

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