linux shell

关注公众号 jb51net

关闭
首页 > 脚本专栏 > linux shell > Shell 进程锁

Shell脚本进程锁机制解析

作者:Redmi人儿

本文主要介绍了Shell脚本中的进程锁机制,用于确保同一时间只有一个实例在运行,通过解析命令行参数、创建锁文件并使用flock命令对文件描述符加锁,感兴趣的可以了解一下

这段 Shell 脚本主要实现了进程锁机制,用于确保同一时间只有一个实例在运行。让我逐行解读:

代码功能分析

1. 命令行参数解析 (第9-21行)

while getopts "m:o:r:" arg; do
    case $arg in
    # ... 参数处理逻辑(代码中省略了具体内容)
    esac
done

2. 文件锁机制 (第23-34行)

这是代码的核心部分:

LOCK_FILE="/tmp/gen_emmc_img.lock"

echo "Waiting for lock for model gen_emmc_img..." 
exec 200>"$LOCK_FILE"      # 将文件描述符200重定向到锁文件
flock 200                  # 对文件描述符200加锁
echo "Lock acquired for gen_emmc_img!"

锁机制的工作原理:

3. 清理和锁释放 (第30-34行)

_cleanup_flock() {
    echo "Releasing lock for gen_emmc_img!"
    flock -u 200           # 释放文件描述符200的锁
}
trap _cleanup_flock EXIT   # 设置陷阱,在脚本退出时自动调用清理函数

设计目的

这种设计主要用于:

典型应用场景

在嵌入式开发或系统镜像生成过程中,这种锁机制很常见,用于保护:

这是一个很经典的 Shell 脚本并发控制实现!

好的,我来深度解读第23-34行的文件锁机制。这部分代码确实比较巧妙,让我详细分解:

逐行深度解析

第23行:定义锁文件路径

LOCK_FILE="/tmp/gen_emmc_img.lock"

第26行:文件描述符重定向

exec 200>"$LOCK_FILE"

这是关键的一步:

第27行:获取文件锁

flock 200

flock 命令的工作原理:

第30-33行:清理函数

_cleanup_flock() {
    echo "Releasing lock for gen_emmc_img!"
    flock -u 200  # 显式释放锁
}

第34行:陷阱设置

trap _cleanup_flock EXIT

trap 的作用:

锁机制的工作原理示意图

进程A启动
    ↓
exec 200>lockfile  # 创建文件描述符
    ↓  
flock 200          # 加锁成功,继续执行
    ↓
[执行关键代码...]
    ↓
脚本结束 → trap触发 → flock -u 200 → 释放锁
进程B启动(当A持有锁时)
    ↓
exec 200>lockfile  # 创建文件描述符
    ↓  
flock 200          # 阻塞等待...
    ↓              # 当进程A释放锁后
flock返回 → 获得锁,继续执行

为什么需要这样设计?

1.原子性操作

# 如果没有flock,你可能会这样写(有竞态条件):
if [ ! -f "$LOCK_FILE" ]; then
    touch "$LOCK_FILE"    # 这里可能有多个进程同时通过检查
    # 执行任务...
    rm "$LOCK_FILE"
fi

2.自动清理保障

即使脚本被 Ctrl+C 中断、发生错误退出,trap EXIT 也能确保锁被释放。

3.避免僵尸锁

传统方法可能因为进程崩溃而留下锁文件,导致系统永久锁定。这里使用内核管理的文件锁,进程退出后锁自动释放。

实际执行流程示例

# 终端1:运行脚本
$ ./gen_emmc_img.sh
Waiting for lock for model gen_emmc_img...
Lock acquired for gen_emmc_img!
[正在执行...]

# 终端2:同时运行另一个实例  
$ ./gen_emmc_img.sh
Waiting for lock for model gen_emmc_img...
# 这里会阻塞等待,直到终端1的脚本结束

# 当终端1脚本结束时:
Releasing lock for gen_emmc_img!
# 终端2立即获得锁并继续执行

文件锁的优势

  1. 跨进程同步:不同shell实例之间可以同步
  2. 自动清理:进程退出时锁自动释放
  3. 内核级别:比基于文件的标记更可靠
  4. 可移植性:大多数Unix-like系统都支持

这种设计在需要保证单实例运行的脚本中非常常见,特别是在处理硬件操作(如eMMC烧录)时尤为重要。

到此这篇关于Shell脚本进程锁机制解析的文章就介绍到这了,更多相关Shell 进程锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文