sync.mutex不能保护文件写入,它仅锁住当前进程内goroutine,无法阻止其他进程(如cron脚本、k8s pod)并发写同一文件;其为用户态内存锁,而文件锁需内核级机制如flock或windows独占句柄。

sync.Mutex 能不能保护文件写入
不能——它只锁住当前进程内的 goroutine,拦不住另一个进程(比如 cron 启动的脚本、K8s 里另一个 Pod)同时打开并写同一个文件。sync.Mutex 是用户态内存锁,生命周期随进程结束而消失;文件锁是内核级资源,绑定 inode 和 fd,哪怕进程崩溃,只要 fd 关闭,锁就自动释放。
常见错误现象:go run -race 报 Write at 0x... by goroutine N;日志行被截断拼接(如 "user logged" 和 "error: timeout" 写成 "user logged error: timeout");文件末尾出现空字节或重复块。
- 仅适用于单进程内多 goroutine 并发写同一
*os.File - 锁对象必须是包级或结构体字段级变量,不能在函数内声明新
sync.Mutex{} -
defer mu.Unlock()必须紧挨mu.Lock(),否则 panic 或死锁风险极高 - 锁内只做纯
Write(),避免fmt.Sprintf、json.Marshal、time.Now().Format()等耗时操作
flock 在 Linux/macOS 上怎么用
标准库没封装,得靠 syscall.Flock,但它只接受已打开的 *os.File 的 fd,且文件必须用 os.O_RDWR 或 os.O_WRONLY 打开(只读无法上写锁)。
加独占锁(写锁):syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB),LOCK_NB 表示非阻塞,失败立刻返回错误,避免 goroutine 卡住;加共享锁(读锁):syscall.Flock(int(f.Fd()), syscall.LOCK_SH|syscall.LOCK_NB);解锁统一用:syscall.Flock(int(f.Fd()), syscall.LOCK_UN)。
Colly 是一个用于 Go 语言的快速开源爬取和爬虫框架。它适用于从简单的页面提取到异步爬虫处理大量页面集合,支持请求回调和结构化解析。
- 务必在
defer f.Close()前调用解锁,否则f.Close()会自动释放锁,但顺序错乱可能引发竞态 -
os.O_APPEND保证单次Write()原子追加,但不防多进程同时写——仍可能两行挤在同一行 - 不要对目标业务文件本身加锁(比如别锁
data.json),应另建data.json.lock
Windows 下怎么实现等效文件锁
syscall.Flock 在 Windows 上未定义,编译直接报错。Windows 没 flock(2),但可用 syscall.CreateFile 配合 FILE_SHARE_NONE 实现路径级独占打开:其他进程再以任何方式打开该路径都会失败。
关键差异:flock 基于 inode,Windows 锁基于路径;若文件被重命名或硬链接,行为不一致;os.Chmod 或 os.Rename 操作被锁文件可能触发权限异常或锁丢失。
- 手动实现需用构建标签分发:
//go:build windows///go:build !windows - 更推荐用
github.com/gofrs/flock,它内部做了平台适配,对外提供统一TryLock()接口 - 初始化:
fileLock := flock.New("/path/to/lockfile"),锁文件路径可任意,不需预先存在 - 锁释放必须显式调用
fileLock.Unlock(),放在defer里最安全
什么时候该用 RWMutex 而不是 Mutex
当读远多于写(比如配置热加载、缓存状态文件),且所有读写都在同一进程内时,sync.RWMutex 更合适:多个 goroutine 可并发 RLock() 读,但写操作会阻塞所有新读和写。
注意:RWMutex 不解决跨进程问题,也不提升写吞吐——写仍是独占;它只是把“读-读”并发放行,避免读请求排队。
- 每个文件应有独立锁,避免共用全局
sync.RWMutex导致无关文件互相阻塞 -
RLock()和Runlock()必须成对,否则后续读可能永远阻塞 - 写操作前必须先
Lock(),写完立刻Unlock(),中间不能混入读逻辑 - 混合读写场景下,如果写频率上升,
RWMutex可能比Mutex更慢(因额外状态管理开销)
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










