
本文详解如何通过goroutine与channel安全、高效地并发写入文件,重点解决因通道阻塞导致的死锁问题,并提供可运行的完整示例与关键注意事项。
本文详解如何通过goroutine与channel安全、高效地并发写入文件,重点解决因通道阻塞导致的死锁问题,并提供可运行的完整示例与关键注意事项。
在Go中利用channel协调并发写文件时,一个常见误区是未及时消费通道数据,从而引发goroutine永久阻塞——这正是原代码无法写入文件的根本原因。output
正确的做法是让消费者(printOutput)先于生产者启动并持续监听通道,确保每次发送都能被即时接收。修改后的代码将 go printOutput() 提前至 main 函数开头,使其作为后台写入服务长期运行:
package main
import (
"fmt"
"os"
"sync"
)
var wg sync.WaitGroup
var output = make(chan string)
func concurrent(n uint64) {
output <p><strong>关键改进与注意事项:</strong> </p>
- 启动顺序决定成败:printOutput 必须作为goroutine提前运行,否则所有 output
- 显式关闭通道:close(output) 是 for range 正常退出的唯一信号,必须在所有发送完成后调用;
- 错误处理增强:f.WriteString 可能失败,应检查返回的 err;
- 文件打开模式优化:os.O_RDWR 改为 os.O_WRONLY 更符合只写场景,权限 0644 比 0666 更安全;
- defer wg.Done() 的陷阱:原代码中 defer 在 concurrent 函数返回后才执行,但此时goroutine可能已退出,wg.Done() 实际未生效——应直接调用 wg.Done()(如示例所示)。
此模式实现了“生产者-消费者”解耦:多个goroutine专注生成数据,单一goroutine串行写入文件,既避免了竞态条件,又保证了I/O效率与数据一致性。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











