登录
首页 >  Golang >  Go问答

以非阻塞方式读取管道数据

来源:stackoverflow

时间:2024-03-10 22:18:26 410浏览 收藏

小伙伴们对Golang编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《以非阻塞方式读取管道数据》,就很适合你,本篇文章讲解的知识点主要包括。在之后的文章中也会多多分享相关知识点,希望对大家的知识积累有所帮助!

问题内容

我想创建一个简单的应用程序,它将连续读取一个应用程序的输出,对其进行处理并将处理后的输出写入标准输出。这个应用程序可以在一秒钟内产生大量数据,然后沉默几分钟。

问题是我的数据处理算法非常慢,因此主循环被阻塞。当循环被阻塞时,我会丢失此时出现的数据。

    cmd := exec.Command("someapp")
    stdoutPipe, _ := cmd.StdoutPipe()
    stdoutReader := bufio.NewReader(stdoutPipe)

    go func() {
        bufioReader := bufio.NewReader(stdoutReader)
        for {
            output, _, err := bufioReader.ReadLine()
            if err != nil || err == io.EOF {
                break
            }

            processedOutput := dataProcessor(output);

            fmt.Print(processedOutput)
        }
    }()

解决这个问题的最好方法可能是缓冲所有输出并在另一个 goroutine 中处理它,但我不确定如何在 golang 中实现它。解决这个问题最惯用的方法是什么?


解决方案


你可以有两个 goroutine,一个是供应商,另一个是消费者。供应商执行命令并通过通道将数据传递给消费者。

cmd := exec.command("someapp")
stdoutpipe, _ := cmd.stdoutpipe()
stdoutreader := bufio.newreader(stdoutpipe)
datas := make(chan data, 100)
go dataprocessor(datas)
    bufioreader := bufio.newreader(stdoutreader)
    for {
        output, _, err := bufioreader.readline()
        var tempdata data
        tempdata.out = output
        if err != nil || err == io.eof {
            break
        }
        datas <- tempdata
        }
}

然后您将在dataprocessor函数中处理数据:

func dataProcessor(Datas <-chan Data)  {
    for  {
        select {
        case data := <-Datas:
        fmt.Println(data)
        default:
            continue
        }
    }
}

显然,这是一个非常简单的示例,您应该对其进行自定义并使其变得更好。搜索通道和 goroutine。阅读 this 教程可能会有所帮助。

理论要掌握,实操不能落!以上关于《以非阻塞方式读取管道数据》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

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