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

Go语言如何并发写入两个不同CSV文件?运行后仅生成文件无数据如何解决

问题根因
  • select中的break无法跳出外层for循环
    你代码里的break语句仅作用于select代码块,执行后仍会回到外层for循环继续执行,导致退出逻辑中的writer.Flush()、file.Close()永远不会被调用,缓冲区数据无法刷入磁盘。
  • csv.Writer缓冲区未主动定期刷新
    encoding/csv的Writer默认带有内存缓冲区,只有缓冲区满或者显式调用Flush()时才会将数据写入磁盘。你仅在退出逻辑中调用了Flush,程序正常运行过程中所有写入的数据都暂存在内存中,不会写入文件。
  • 异常终止时退出逻辑不执行
    你的main函数靠time.Sleep等待10分钟,如果你提前终止程序(比如按Ctrl+C),defer定义的Stop方法不会执行,QuitChan不会被关闭,退出逻辑永远不会触发。
  • 额外说明:两个服务操作不同文件,不存在写入竞争,不需要加mutex,加了也无法解决当前问题。
修复方案
  1. 修正循环跳出逻辑,收到退出信号后直接return退出函数即可,不需要break:
case <-a.QuitChan:
    ticker.Stop()
    writer.Flush()
    // 可追加检查Flush错误:if err := writer.Error(); err != nil { fmt.Println(err) }
    file_one.Close()
    fmt.Println("Stopped recording.")
    return // 直接退出record函数
  1. 每次写入数据后主动Flush,保证数据及时写入磁盘:
err = writer.Write(header)
if err != nil {
    fmt.Println(err)
    return
}
writer.Flush() // 写入表头后刷入磁盘
// 定时任务写入后也追加Flush
err = writer.Write([]string{fmt.Sprintf("%2d:%2d:%2d", t.Hour(), t.Minute(), t.Second())})
if err != nil {
    fmt.Println(err)
    a.QuitChan <- struct{}{}
}
writer.Flush() // 写入行后刷入磁盘
  1. 增加系统信号监听,保证程序被手动终止时也能执行退出逻辑,替换main函数里的time.Sleep(600*time.Second)即可:
// 需提前导入 os/signal、syscall 包
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
<-sigChan // 阻塞到收到中断信号

内容的提问来源于stack exchange,提问作者Paul Côté

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 13:06:06