You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go可组合goroutine管道使用scanner.Scan()读文件的同步问题

问题根源

判断正确,核心问题是文件关闭时机错误。readValuesFromFile函数启动标注(1)的goroutine后会立即返回,函数返回时触发外层的defer file.Close()执行,直接关闭了文件描述符。此时子goroutine中scanner.Scan()才开始读取已关闭的文件,自然无法读取到有效内容。
替换为直接写入随机字符串的场景下不需要操作文件描述符,所以不会受文件提前关闭的影响,流水线可以正常运行。

修复方案

最符合Go语言惯例的修复方式是将文件关闭逻辑移入子goroutine内部,确保所有文件读取操作完成后再释放文件资源:

func readValuesFromFile(filename string) <-chan string {
    file, err := os.Open(filename)
    if err != nil {
        log.Fatal(err)
    }

    inputStream := make(chan string)

    go func() { //(1)
        // defer移至此处,子goroutine执行完成前再关闭文件
        defer file.Close()
        count := 0
        scanner := bufio.NewScanner(file)
        for scanner.Scan() { // (2)
            inputStream <- strings.TrimSpace(scanner.Text())
            count = count + 1
        }
        // 补充 scanner 错误处理,避免读取出错无感知
        if err := scanner.Err(); err != nil {
            log.Printf("文件读取异常: %v", err)
        }
        close(inputStream)
    }()
    return inputStream
}
补充说明

当前流水线的整体调度逻辑没有问题:主goroutine会阻塞在writeResults函数内持续读取通道内容,直到通道被关闭才会退出,不会出现子goroutine未执行完成主进程就提前终止的情况。

内容的提问来源于stack exchange,提问作者DraQ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 02:06:03