Shell腳本進(jìn)程鎖機(jī)制解析
這段 Shell 腳本主要實(shí)現(xiàn)了進(jìn)程鎖機(jī)制,用于確保同一時(shí)間只有一個(gè)實(shí)例在運(yùn)行。讓我逐行解讀:
代碼功能分析
1. 命令行參數(shù)解析 (第9-21行)
while getopts "m:o:r:" arg; do
case $arg in
# ... 參數(shù)處理邏輯(代碼中省略了具體內(nèi)容)
esac
done
- 使用
getopts解析命令行參數(shù) - 支持三個(gè)帶參數(shù)的選項(xiàng):
-m、-o、-r - 具體處理邏輯在代碼中被省略了
2. 文件鎖機(jī)制 (第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 # 對(duì)文件描述符200加鎖 echo "Lock acquired for gen_emmc_img!"
鎖機(jī)制的工作原理:
- 創(chuàng)建鎖文件
/tmp/gen_emmc_img.lock - 使用
flock命令對(duì)文件描述符200加鎖 - 如果鎖已被占用,腳本會(huì)阻塞等待直到鎖可用
3. 清理和鎖釋放 (第30-34行)
_cleanup_flock() {
echo "Releasing lock for gen_emmc_img!"
flock -u 200 # 釋放文件描述符200的鎖
}
trap _cleanup_flock EXIT # 設(shè)置陷阱,在腳本退出時(shí)自動(dòng)調(diào)用清理函數(shù)
設(shè)計(jì)目的
這種設(shè)計(jì)主要用于:
- 防止并發(fā)沖突:確保同一時(shí)間只有一個(gè)
gen_emmc_img.sh進(jìn)程在運(yùn)行 - 資源保護(hù):在生成 eMMC 鏡像時(shí)避免多個(gè)進(jìn)程同時(shí)操作導(dǎo)致的沖突
- 自動(dòng)清理:使用
trap確保即使腳本異常退出也能釋放鎖
典型應(yīng)用場(chǎng)景
在嵌入式開發(fā)或系統(tǒng)鏡像生成過程中,這種鎖機(jī)制很常見,用于保護(hù):
- 對(duì)存儲(chǔ)設(shè)備的獨(dú)占訪問
- 臨時(shí)文件的創(chuàng)建和使用
- 系統(tǒng)關(guān)鍵資源的訪問
這是一個(gè)很經(jīng)典的 Shell 腳本并發(fā)控制實(shí)現(xiàn)!
好的,我來深度解讀第23-34行的文件鎖機(jī)制。這部分代碼確實(shí)比較巧妙,讓我詳細(xì)分解:
逐行深度解析
第23行:定義鎖文件路徑
LOCK_FILE="/tmp/gen_emmc_img.lock"
- 在系統(tǒng)的臨時(shí)目錄創(chuàng)建一個(gè)鎖文件
- 文件名包含腳本名稱,避免與其他腳本沖突
第26行:文件描述符重定向
exec 200>"$LOCK_FILE"
這是關(guān)鍵的一步:
exec命令在當(dāng)前shell進(jìn)程中執(zhí)行重定向200>表示將文件描述符200重定向到鎖文件- 如果文件不存在會(huì)自動(dòng)創(chuàng)建,存在則截?cái)?/li>
- 文件描述符200是一個(gè)任意選擇的大于2的數(shù)字(避免與stdin=0, stdout=1, stderr=2沖突)
第27行:獲取文件鎖
flock 200
flock 命令的工作原理:
- 對(duì)文件描述符200指向的文件加鎖
- 這是** advisory lock**(建議性鎖),不是強(qiáng)制性鎖
- 如果鎖已被其他進(jìn)程持有,當(dāng)前進(jìn)程會(huì)阻塞等待
- 鎖的釋放發(fā)生在文件描述符關(guān)閉時(shí)
第30-33行:清理函數(shù)
_cleanup_flock() {
echo "Releasing lock for gen_emmc_img!"
flock -u 200 # 顯式釋放鎖
}
第34行:陷阱設(shè)置
trap _cleanup_flock EXIT
trap 的作用:
- 注冊(cè)一個(gè)信號(hào)處理程序
EXIT是一個(gè)偽信號(hào),在shell退出時(shí)觸發(fā)- 無論腳本正常結(jié)束還是異常退出,都會(huì)調(diào)用
_cleanup_flock
鎖機(jī)制的工作原理示意圖
進(jìn)程A啟動(dòng)
↓
exec 200>lockfile # 創(chuàng)建文件描述符
↓
flock 200 # 加鎖成功,繼續(xù)執(zhí)行
↓
[執(zhí)行關(guān)鍵代碼...]
↓
腳本結(jié)束 → trap觸發(fā) → flock -u 200 → 釋放鎖
進(jìn)程B啟動(dòng)(當(dāng)A持有鎖時(shí))
↓
exec 200>lockfile # 創(chuàng)建文件描述符
↓
flock 200 # 阻塞等待...
↓ # 當(dāng)進(jìn)程A釋放鎖后
flock返回 → 獲得鎖,繼續(xù)執(zhí)行
為什么需要這樣設(shè)計(jì)?
1.原子性操作
# 如果沒有flock,你可能會(huì)這樣寫(有競(jìng)態(tài)條件):
if [ ! -f "$LOCK_FILE" ]; then
touch "$LOCK_FILE" # 這里可能有多個(gè)進(jìn)程同時(shí)通過檢查
# 執(zhí)行任務(wù)...
rm "$LOCK_FILE"
fi
2.自動(dòng)清理保障
即使腳本被 Ctrl+C 中斷、發(fā)生錯(cuò)誤退出,trap EXIT 也能確保鎖被釋放。
3.避免僵尸鎖
傳統(tǒng)方法可能因?yàn)檫M(jìn)程崩潰而留下鎖文件,導(dǎo)致系統(tǒng)永久鎖定。這里使用內(nèi)核管理的文件鎖,進(jìn)程退出后鎖自動(dòng)釋放。
實(shí)際執(zhí)行流程示例
# 終端1:運(yùn)行腳本 $ ./gen_emmc_img.sh Waiting for lock for model gen_emmc_img... Lock acquired for gen_emmc_img! [正在執(zhí)行...] # 終端2:同時(shí)運(yùn)行另一個(gè)實(shí)例 $ ./gen_emmc_img.sh Waiting for lock for model gen_emmc_img... # 這里會(huì)阻塞等待,直到終端1的腳本結(jié)束 # 當(dāng)終端1腳本結(jié)束時(shí): Releasing lock for gen_emmc_img! # 終端2立即獲得鎖并繼續(xù)執(zhí)行
文件鎖的優(yōu)勢(shì)
- 跨進(jìn)程同步:不同shell實(shí)例之間可以同步
- 自動(dòng)清理:進(jìn)程退出時(shí)鎖自動(dòng)釋放
- 內(nèi)核級(jí)別:比基于文件的標(biāo)記更可靠
- 可移植性:大多數(shù)Unix-like系統(tǒng)都支持
這種設(shè)計(jì)在需要保證單實(shí)例運(yùn)行的腳本中非常常見,特別是在處理硬件操作(如eMMC燒錄)時(shí)尤為重要。
到此這篇關(guān)于Shell腳本進(jìn)程鎖機(jī)制解析的文章就介紹到這了,更多相關(guān)Shell 進(jìn)程鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
shell for循環(huán)、循環(huán)變量值付給其他shell腳本的方法
今天小編就為大家分享一篇shell for循環(huán)、循環(huán)變量值付給其他shell腳本的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-06-06
linux 使用NSF 映射遠(yuǎn)程磁盤目錄的實(shí)現(xiàn)
下面小編就為大家?guī)硪黄猯inux 使用NSF 映射遠(yuǎn)程磁盤目錄的實(shí)現(xiàn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02
檢查Linux系統(tǒng)中文件大小的方法總結(jié)
在Linux操作系統(tǒng)中,掌握如何高效檢查文件大小是每位開發(fā)者和系統(tǒng)管理員的必備技能,本文詳細(xì)介紹了四種檢查Linux文件大小的方法,感興趣的朋友可以參考下2024-03-03
shell腳本批量執(zhí)行指定路徑下sql腳本的實(shí)現(xiàn)
本文主要介紹了shell腳本批量執(zhí)行指定路徑下sql腳本的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
Shell之function函數(shù)的定義及調(diào)用示例
本文主要介紹了Shell之function函數(shù)的定義及調(diào)用示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
shell腳本殺死指定端口進(jìn)程的實(shí)現(xiàn)示例
隨著越來越廣泛的Linux系統(tǒng)使用,如何輕松殺死指定程序端口成為了很多系統(tǒng)管理員最迫切關(guān)心的問題,本文就詳細(xì)的介紹一下如何實(shí)現(xiàn),感興趣的可以了解一下2023-10-10

