linux shell并发需配合锁机制防竞争,常用flock实现文件锁,支持阻塞/非阻塞模式;无flock时可用mkdir原子性模拟锁;控制并发数推荐sem或parallel;须规避管道子shell锁失效、nfs不兼容及锁路径不一致等问题。

Linux Shell 中实现并发执行时,必须配合合理的并发控制与锁机制,否则容易出现资源竞争、数据错乱或重复执行等问题。核心思路是:用进程隔离保证并行效率,用文件锁或信号量等手段保证关键操作的互斥性。
使用 flock 实现轻量级文件锁
flock 是 Shell 并发控制最常用、最便捷的方式,它基于内核文件描述符锁,无需额外服务,支持排他锁(写锁)和共享锁(读锁),且自动随进程退出释放。
- 基本用法:
flock /tmp/mylock -c "command",命令执行完自动解锁 - 在脚本中封装更安全:
exec 200>/tmp/global.lock
flock -n 200 || { echo "获取锁失败,退出"; exit 1; }
# 执行临界区逻辑
echo "正在更新共享配置..." >> /var/log/app.log
# ...
flock -u 200 - -n 表示非阻塞,抢锁失败立即返回;不加则会等待(可能无限挂起)
用临时文件 + 原子重命名模拟“检查-设置”锁
在不支持 flock 的极简环境(如某些容器或 busybox)中,可用 mkdir 的原子性实现互斥——因为 mkdir 天然不可重入:
websenB2B是一套经过完善设计的B2B行业网站程序,是windows nt系列环境下最佳的B2B行业网产站解决方案。精心设计的架构与功能机制,适合从个人到企业各方面应用的要求,为您提供一个安全、稳定、高效、易用而快捷的行业网站商务系统。分普及版和商业版等不同版本。一、网胜B2B电子商务系统SP6.2蓝色风格普及版本升级功能说明:1、邮件群发功能:可以选择某一级别的会员,并放入支持html
if mkdir /tmp/lock.dir 2>/dev/null; then echo "获得锁"; else echo "锁已被占用"; fi- 临界区结束后用
rmdir /tmp/lock.dir释放(注意仅限单机,且需确保无残留) - 适合短时、低频、无复杂依赖的场景,例如防止同一脚本被重复触发
限制并发数量:sem 和 parallel 工具
当需要控制“最多 N 个任务同时运行”,而非完全互斥时,可借助外部工具:
-
GNU parallel:内置并发控制,
cat tasks.txt | parallel -j 4 ./process.sh {}表示最多 4 个进程并行 -
sem(来自 GNU parallel 包):配合 flock 使用,
sem -j 3 --id myjob ./task.sh arg1可跨脚本协调同名任务的并发上限 - 纯 Shell 模拟较繁琐(需维护后台作业计数+wait -n),不建议自行实现
避免常见陷阱
并发 Shell 脚本容易踩坑,关键点在于理解锁的作用域和生命周期:
- 管道中的子 shell 无法继承父进程的文件描述符锁,
flock -e 200; echo "x" | while read line; do ...; done会导致锁失效——应改用while ... done 或把整个循环包进 <code>flock -c - 不要对 NFS 挂载点上的文件使用 flock(部分 NFS 版本不支持强制锁)
- 多个脚本若共用同一锁路径,务必确保路径绝对、一致,且有足够权限









