Go 扫描缓冲区有时会挂起

标签 go

我使用以下代码,工作正常,但在某些情况下,进程卡住,我看不到任何输出。例如,此代码运行 npm installmvn clean install 并且大多数时候它运行良好,但有时它会挂起并且您没有得到任何输出

func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {
    scanout := bufio.NewScanner(stdout)
    scanerr := bufio.NewScanner(stderr)

    scanout.Split(bufio.ScanRunes)
    for scanout.Scan() {
        fmt.Print(scanout.Text())
    }

    scanerr.Split(bufio.ScanRunes)
    for scanerr.Scan() {
        fmt.Print(scanerr.Text())
    }
    return scanout, scanerr
}

现在,如果我更改如下顺序(首先是错误,第二是标准输出),当命令挂起时,我会收到一些错误输出,但是我看不到在线输出,当您运行命令时,您会看到一些输出,当完成时剩下的你都看到了。您可以等待输出 2 分钟或更长时间,并在过程结束时立即获得长输出。

如何修复我能够在线获取输出并在进程挂起时获得一些反馈?

func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {
    scanout := bufio.NewScanner(stdout)
    scanerr := bufio.NewScanner(stderr)

    scanout.Split(bufio.ScanRunes)
    for scanout.Scan() {
        fmt.Print(scanout.Text())
    }
    scanerr.Split(bufio.ScanRunes)
    for scanerr.Scan() {
        fmt.Print(scanerr.Text())
    }


    }
    return scanout, scanerr
}

更新

应该是这样吗?

func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {

scanout := bufio.NewScanner(stdout)
scanout.Split(bufio.ScanRunes)
go func() {
    for scanout.Scan() {
        fmt.Print(scanout.Text())
     }
}()

go func() {
scanerr.Split(bufio.ScanRunes)
        for scanerr.Scan() {
            fmt.Print(scanerr.Text())
        }
}()

}

最佳答案

在第一种情况下,您将从进程的标准输出中读取数据,直到进程结束。然后你从 stderr 中读取。在第二种情况下,您首先读取 err,然后读取 out。你应该阅读他们的文章。要么使用 Cmd.CombinedOutput 这将返回它们,要么启动两个 goroutine,一个从 stdin 读取,一个从 stderr 读取,直到流关闭。

scanout := bufio.NewScanner(stdout)
scanout.Split(bufio.ScanRunes)
go func() {
    for scanout.Scan() {
        fmt.Print(scanout.Text())
     }
}()

关于Go 扫描缓冲区有时会挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58793004/

相关文章:

go - 什么是 C++ 初始化列表的 Go 等价物?

sql - gorm 是否用逻辑 OR 解释结构体的内容?

go - 我应该什么时候关闭这个简单的网络应用程序中的数据库连接?

go - 尝试将提取的文件名插入单个文件

json - 如何在 golang 中将 spanner 行提取为 Json 或 Parquet 格式?

go - 如何在模板中声明全局变量?

docker - docker golang主进程与python子进程通信的最佳实践

ssl - 如何在 Go 中建立到 memsql 的基于 ssl 的 tcp 连接

variables - 短声明运算符隐藏全局变量

go - Rob Pike 在 Go 中的 "the synchronization nature of the channels"是什么意思?