下面是我的代码(writeFromProcessToFileWithMax是一个内部函数,工作正常):

    // Go routines for non-blocking reading of stdout and stderr and writing to files
    g := new(errgroup.Group)

    // Read stdout in goroutine.
    g.Go(func() error {
        err = writeFromProcessToFileWithMax(stdoutScanner, stdoutFileWriter, maxStdoutFileLengthInGB)
        if err != nil {
            log.Error().Err(err).Msgf("Error writing to stdout file: %s", stdoutFilename)
            return err
        }
        return nil
    })

    // Read stderr in goroutine.
    g.Go(func() error {
        err = writeFromProcessToFileWithMax(stderrScanner, stderrFileWriter, maxStderrFileLengthInGB)
        if err != nil {
            log.Error().Err(err).Msgf("Error writing to stderr file: %s", stderrFilename)
            return err
        }
        return nil
    })

    // Wait the command in a goroutine.
    g.Go(func() error {
        return cmd.Wait()
    })

    // Starting the command
    if err = cmd.Start(); err != nil {
        log.Error().Err(err).Msg("Error starting command")
        return err
    }

    // Waiting until errorGroups groups are done
    if err = g.Wait(); err != nil {
        log.Error().Err(err).Msg("Error during running of the command")
    }

当我运行它时,我得到以下错误=Error during running of the command error="exec: not started".但一切都运行正常.

它会回来咬我还是我应该压抑?

推荐答案

你要等cmd岁才能开始.在旧代码中,cmd.Wait()将在cmd.Start() most of the time之前被调用.(除非您显式使用同步点,否则无法保证两个不同Goroutine中的事情在彼此之间发生的确切时间)

在Goroutine中交换cmd.Start()cmd.Wait()的顺序:

// Starting the command
if err = cmd.Start(); err != nil {
    log.Error().Err(err).Msg("Error starting command")
    return err
}

// Wait the command in a goroutine.
g.Go(func() error {
    return cmd.Wait()
})

当您start启动命令后等待的Goroutine时,您可以保证以正确的顺序执行cmd.Start()cmd.Wait().

至于为什么它似乎奏效了:在团队中第一个失败的大猩猩之后(或者在所有成功完成之后),g.Wait()个返回.由于执行cmd.Wait()的Goroutine失败,因此在将进程输出写入文件的Goroutine完成之前返回g.Wait().

因此,它并没有真正起作用;当您期望文件写入完成时,它并没有完成,如果您在那时退出了该过程,或者试图读取文件,您可能已经看到了不完整的数据.

Go相关问答推荐

Makefile:现有文件上没有这样的文件或目录,不加载环境变量

难以为多个平台添加Go Bazel构建选项

链自定义GRPC客户端拦截器/DialOptions

是不是有什么原因导致`Strings.EqualFold`不先进行长度比较?

如何在VSCode中为特定的.go文件创建调试配置?

golang regex基于关键字拆分字符串

这是go语言gin提供的关于TypeEngine和RouterGroup的问题

Golang:访问any类型泛型上的字段

如何使用 html/template 在 golang 中运行一个范围内的范围

htmx 表单 + gin 无法正确读取请求正文

Kperf 构建失败

Opensearch 错误 ping 弹性服务器:由未知权威签署的 x509 证书

将值发送到 Channel 并在就绪时读取输出

Gorm 预加载给出了模糊的列错误

如何将元素从一个切片移动到另一个切片

try 与 golang testify/suite 并行运行测试失败

GoReleaser 和 ssh-agent Github 操作:为什么无法读取用户名...终端提示已禁用?

try 创建新的 etcdv3 客户端时出现pc error: code = Unavailable desc = error reading from server: EOF

Golang LinkedList 删除第一个元素

Go 语言的select语句