为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 频道问题

Golang 频道问题

Go
有只小跳蛙 2022-05-23 18:08:21
我有一个简单的频道示例:https: //play.golang.org/p/eLcpzXeCHmspackage mainimport (    "fmt")func execute(trueChan chan<- bool, lowerRange int32, upperRange int32) {    for lowerRange <= upperRange {        fmt.Printf("\nhandling number %v", lowerRange)        if lowerRange%2 == 0 {            go func() {                trueChan <- true            }()        }        lowerRange++    }    close(trueChan)}func main() {    counter := 0    trueChan := make(chan bool)    execute(trueChan, 5, 25)    for {        if _, ok := <-trueChan; ok {            counter++        } else {            break        }    }    fmt.Printf("\n%v", counter)}第一个问题:我有时会收到一条错误消息...handling number 5handling number 6handling number 7handling number 8handling number 9handling number 10handling number 11handling number 12handling number 13handling number 14handling number 15handling number 16handling number 17handling number 18handling number 19handling number 20handling number 21handling number 22handling number 23handling number 24handling number 250panic: send on closed channel第二个问题 - 我的计数器始终为 0。有人可以给我一个提示,我做错了什么?
查看完整描述

2 回答

?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

你的代码:

  1. 创建一个无缓冲的通道trueChan

  2. 创建 10 个 goroutine,每个 goroutine 都将尝试写入trueChan,这将阻塞直到有东西从中读取。

  3. 关闭trueChan,然后返回main()

  4. main()打印0,因为它还没有从 goroutine 中读取任何内容

  5. 同时,由于trueChan在步骤 3 中关闭,在 goroutine 完成使用它之前,第一个尝试写入通道的 goroutine 出现恐慌

至少,在trueChan您知道所有 goroutine 都已完成之前,您不应该关闭它。实际上,您甚至在他们开始使用它之前就将其关闭。

Async.WaitGroup可能是做到这一点的一种方法,但在你的代码中如何做到这一点并不明显,因为我不完全确定你的目标。这段代码看起来像一个简单的练习,而不是一个真实的例子。如果你能解释你的目标,我可能会提供更具体的建议。


查看完整回答
反对 回复 2022-05-23
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

您的第一个和第二个问题在同一个根源:

您在主程序中关闭通道,程序关闭通道,在您的例程将数据发送到通道之前退出程序您

通常必须在使用该程序的延迟中关闭通道香奈儿。例如,对于 yout 代码的修复:


package main


import (

    "fmt"

)


func execute(trueChan chan<- bool, lowerRange int32, upperRange int32) {

    go func() {

        defer func(){

            close (trueChan)

        }()

        for lowerRange <= upperRange {

            fmt.Printf("\n handling number %v", lowerRange)

            if lowerRange%2 == 0 {

                trueChan <- true

            }

            lowerRange++

        }


    }()

}


func main() {

    counter := 0


    trueChan := make(chan bool)


    execute(trueChan, 5, 25)


    for _ = range trueChan{ // For small improvement here. Ref as below 

            counter++

    }


    fmt.Printf("\n%v", counter)

}


https://tour.golang.org/concurrency/4


查看完整回答
反对 回复 2022-05-23
  • 2 回答
  • 0 关注
  • 106 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信