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

从接收通道阻塞

从接收通道阻塞

Go
鸿蒙传说 2021-12-27 17:55:52
我有以下 go 代码来等待流。预期的输出是:line1line2line3line4line5escape1scan donedone....但是之后line5,我的代码一直挂着。var lines = `line1line2line3line4line5line6line7`func main() {    var (        donec  = make(chan struct{})        stream = make(chan string, 5000)        exitc  = make(chan struct{})    )    go func() {        scanner := bufio.NewScanner(strings.NewReader(lines))    escape1:        for {            for scanner.Scan() {                select {                case <-donec:                    fmt.Println("escape1")                    close(stream)                    break escape1                default:                    stream <- scanner.Text()                }            }        }        close(exitc)        fmt.Println("scan done")        return    }()escape2:    for {        select {        case txt, ok := <-stream:            if !ok {                fmt.Println("stream closed!")            }            fmt.Println(txt)            if strings.Contains(txt, "line5") {                close(donec)                <-exitc                break escape2            }        }    }    fmt.Println("done....")}认为我做的一切都是正确的。有人可以帮我调试这个挂起的代码吗?
查看完整描述

1 回答

?
神不在的星期二

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

我认为这是因为您的escape1for 循环包装了for scanner.Scan()循环。


当我删除那个外部 for 循环时,它对我来说很好用:https : //play.golang.org/p/NU3m3Deil7


func main() {

    var (

        donec  = make(chan struct{})

        stream = make(chan string, 5000)

        exitc  = make(chan struct{})

    )

    go func() {

        scanner := bufio.NewScanner(strings.NewReader(lines))

    escape1:

        for scanner.Scan() {

            select {

            case <-donec:

                fmt.Println("escape1")

                close(stream)

                break escape1

            default:

                stream <- scanner.Text()

            }

        }


        close(exitc)

        fmt.Println("scan done")

        return

    }()


escape2:

    for {

        select {

        case txt, ok := <-stream:

            if !ok {

                fmt.Println("stream closed!")

            }

            fmt.Println(txt)

            if strings.Contains(txt, "line5") {

                close(donec)

                <-exitc

                break escape2

            }

        }

    }

    fmt.Println("done....")

}


查看完整回答
反对 回复 2021-12-27
  • 1 回答
  • 0 关注
  • 177 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号