首页/系统/Linux 运维命令速查/flock 文件锁防并发执行
进程与作业69 条

flock 文件锁防并发执行

互斥跑批的轻量方案:同一把锁同时只允许一个实例运行,cron 重叠、脚本防重入的标准解法;进程退出锁自动释放。

Linux 运维命令速查系统更新于 2026-10-13

flock 是什么

flock 利用内核的 flock 系统调用对文件加锁,用来保证同一时刻只有一个实例在跑。它的典型用法是包住一条命令:拿不到锁就退出或等待。锁由内核维护、不写进文件内容,进程退出或崩溃时锁自动释放,所以不会出现「陈旧的死锁文件」导致任务永远跑不起来。

基本信息

适用平台Linux/Unix(util-linux 提供命令,脚本里也可用 flock 系统调用)
命令语法flock [选项] 锁文件 命令 / flock [选项] 数字fd
常用选项-n 拿不到锁立即失败 -w 秒数 限时等待 -c 以字符串形式给命令 -s 共享锁 -x 独占锁(默认)
默认行为不加 -n 或 -w 时会一直排队等待,这在 cron 场景会造成进程堆积
退出码拿不到锁时返回非零(默认 1,可用 -E 指定)

典型使用场景

  • 防定时任务重叠:上一次还没跑完,这次直接跳过
  • 脚本重入保护:手动执行时避免与定时任务撞车
  • 串行化资源访问:多实例共享同一份数据时保证顺序
  • 批量运维节流:确保同类操作不会并发压垮目标
  • 发布流程加锁:避免两次发布同时进行

常用示例

常用示例
flock -n /var/lock/backup.lock -c '/usr/local/bin/backup.sh'    # 拿不到锁立刻退出
flock -w 30 /var/lock/sync.lock /usr/local/bin/sync.sh            # 最多等 30 秒
# cron 防重叠的标准写法
*/10 * * * * /usr/bin/flock -n /var/lock/report.lock /usr/local/bin/report.sh
# 脚本内分段持锁(fd 形式)
exec 9>/var/lock/app.lock
flock -n 9 || { echo '已有实例在跑'; exit 1; }
# 后续业务逻辑……
exec 9>&-      # 释放

常用选项读法

选项作用注意
-n非阻塞,拿不到锁立即失败cron 与自动化场景必加
-w 秒限时等待,超时失败介于等待与立即失败之间的折中
-c 字符串把命令作为字符串传入注意引号嵌套
-s 与 -x共享锁与独占锁默认独占,读多写少场景可用共享锁
数字 fd在脚本内对已打开的文件描述符加锁适合分段持锁
-E 数字自定义冲突时的退出码便于上层判断是「已有实例」还是别的问题
锁由内核的 flock 调用维护,不写进文件内容:进程正常退出、被 kill 或崩溃,锁都会随文件描述符关闭而释放。所以「锁文件还在磁盘上」并不代表任务还在跑,判断是否在运行要看进程而不是看文件。
跨主机互斥不要依赖 flock:NFS 上的锁语义受挂载选项与版本影响,行为可能与本地不同。需要跨主机串行时,用数据库行锁、分布式锁服务或带幂等的任务调度来保证。

易错点

  • cron 场景不加 -n 会排队堆叠:上一次没跑完时新实例一直等,越积越多
  • NFS 上 flock 语义受挂载与版本影响,跨主机互斥不要依赖它
  • -c 传入的命令是字符串,引号嵌套容易出错,复杂逻辑建议写成脚本文件再调用
  • 锁文件路径要在同类任务间唯一:多个任务共用同一个锁文件会互相阻塞
  • 锁只保证互斥,不保证「上一次的残留状态已清理」,任务内部仍需幂等设计

数据来源与参考

  • man 1 flock(util-linux 手册)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌