Shell脚本进程锁机制解析

 更新时间:2025年11月30日 09:51:37   作者:Redmi人儿  
本文主要介绍了Shell脚本中的进程锁机制,用于确保同一时间只有一个实例在运行,通过解析命令行参数、创建锁文件并使用flock命令对文件描述符加锁,感兴趣的可以了解一下

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

代码功能分析

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

while getopts "m:o:r:" arg; do
    case $arg in
    # ... 参数处理逻辑(代码中省略了具体内容)
    esac
done
  • 使用 getopts 解析命令行参数
  • 支持三个带参数的选项:-m-o-r
  • 具体处理逻辑在代码中被省略了

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!"

锁机制的工作原理:

  • 创建锁文件 /tmp/gen_emmc_img.lock
  • 使用 flock 命令对文件描述符200加锁
  • 如果锁已被占用,脚本会阻塞等待直到锁可用

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

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

设计目的

这种设计主要用于:

  • 防止并发冲突:确保同一时间只有一个 gen_emmc_img.sh 进程在运行
  • 资源保护:在生成 eMMC 镜像时避免多个进程同时操作导致的冲突
  • 自动清理:使用 trap 确保即使脚本异常退出也能释放锁

典型应用场景

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

  • 对存储设备的独占访问
  • 临时文件的创建和使用
  • 系统关键资源的访问

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

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

逐行深度解析

第23行:定义锁文件路径

LOCK_FILE="/tmp/gen_emmc_img.lock"
  • 在系统的临时目录创建一个锁文件
  • 文件名包含脚本名称,避免与其他脚本冲突

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

exec 200>"$LOCK_FILE"

这是关键的一步:

  • exec 命令在当前shell进程中执行重定向
  • 200> 表示将文件描述符200重定向到锁文件
  • 如果文件不存在会自动创建,存在则截断
  • 文件描述符200是一个任意选择的大于2的数字(避免与stdin=0, stdout=1, stderr=2冲突)

第27行:获取文件锁

flock 200

flock 命令的工作原理:

  • 对文件描述符200指向的文件加锁
  • 这是** advisory lock**(建议性锁),不是强制性锁
  • 如果锁已被其他进程持有,当前进程会阻塞等待
  • 锁的释放发生在文件描述符关闭时

第30-33行:清理函数

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

第34行:陷阱设置

trap _cleanup_flock EXIT

trap 的作用:

  • 注册一个信号处理程序
  • EXIT 是一个伪信号,在shell退出时触发
  • 无论脚本正常结束还是异常退出,都会调用 _cleanup_flock

锁机制的工作原理示意图

进程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 进程锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Linux 文件查找打包压缩及解压命令详解

    Linux 文件查找打包压缩及解压命令详解

    这篇文章主要介绍了Linux 文件查找,打包压缩及解压,文件查找和压缩解压是Linux系统中非常常见的操作,掌握了相关命令和技巧,可以提高我们的工作效率和文件管理能力,需要的朋友可以参考下
    2023-11-11
  • shell for循环、循环变量值付给其他shell脚本的方法

    shell for循环、循环变量值付给其他shell脚本的方法

    今天小编就为大家分享一篇shell for循环、循环变量值付给其他shell脚本的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-06-06
  • Linux进程管理方法介绍

    Linux进程管理方法介绍

    这篇文章介绍了Linux进程管理的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • linux 使用NSF 映射远程磁盘目录的实现

    linux 使用NSF 映射远程磁盘目录的实现

    下面小编就为大家带来一篇linux 使用NSF 映射远程磁盘目录的实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • 5个实用的shell脚本面试题和答案

    5个实用的shell脚本面试题和答案

    这篇文章主要介绍了5个实用的shell脚本面试题和答案,给出的脚本堪称编码规范,麻雀虽小,异常处理,友好提示,一应俱全,值得学习,需要的朋友可以参考下
    2014-06-06
  • 检查Linux系统中文件大小的方法总结

    检查Linux系统中文件大小的方法总结

    在Linux操作系统中,掌握如何高效检查文件大小是每位开发者和系统管理员的必备技能,本文详细介绍了四种检查Linux文件大小的方法,感兴趣的朋友可以参考下
    2024-03-03
  • Linux shell常用的73条命令总结

    Linux shell常用的73条命令总结

    对于经常使用linux系统的朋友们来说,基本常用的shell命令是少不了的,下面这篇文中就为大家总结了Linux shell的常用命令,有需要的朋友们可以参考借鉴,下面来一起学习学习吧。
    2017-01-01
  • shell脚本批量执行指定路径下sql脚本的实现

    shell脚本批量执行指定路径下sql脚本的实现

    本文主要介绍了shell脚本批量执行指定路径下sql脚本的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • Shell之function函数的定义及调用示例

    Shell之function函数的定义及调用示例

    本文主要介绍了Shell之function函数的定义及调用示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • shell脚本杀死指定端口进程的实现示例

    shell脚本杀死指定端口进程的实现示例

    随着越来越广泛的Linux系统使用,如何轻松杀死指定程序端口成为了很多系统管理员最迫切关心的问题,本文就详细的介绍一下如何实现,感兴趣的可以了解一下
    2023-10-10

最新评论