Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux flock 命令實現腳本級互斥鎖:並發控制、異步等待、共享/獨佔模式全解析

編輯:Linux 教學

Shell 腳本中需要**多進程協同、互斥執行、異步等待完成**時,flock(1) 是比臨時文件、目錄鎖更標準、更可靠的工具。本文通過「並發更新多台服務器套件、等待全部完成再執行後續任務」的實戰場景,詳細講解 flock 的三種調用形式、共享/獨佔鎖語義、非阻塞/超時參數、文件描述符綁定模式,並給出可直接複製的生產級模板。

場景痛點

# 串行執行:慢
update_pkg_on_machine_1
update_pkg_on_machine_2
update_pkg_on_machine_3

# 後台 & + sleep:不可靠
update_pkg_on_machine_1 &
update_pkg_on_machine_2 &
update_pkg_on_machine_3 &
sleep 10   # 10 秒夠嗎?夠不夠都不好

flock 核心模型

  • 鎖對象:一個文件或目錄(自動創建),或已打開的文件描述符。
  • 鎖類型:
    • 共享鎖 (Shared, -s):多進程可同時持有,適合「讀/並發任務」。
    • 獨佔鎖 (Exclusive, -x, 默認):同一時刻僅一進程持有,適合「寫/串行關鍵區」。
  • 互斥規則:共享鎖與獨佔鎖**互斥**,共享鎖之間**不互斥**,獨佔鎖之間**互斥**。
  • 生命週期:進程獲取鎖 → 執行命令/代碼塊 → 釋放鎖(文件描述符關閉時自動釋放)。

三種調用形式

1. 包裹命令模式(最常用)

flock [選項] 鎖文件 -c "命令"
flock [選項] 鎖文件 命令 [參數...]

2. 代碼塊模式(腳本內部精細控制)

(
  flock -s 200
  # ... 並發安全代碼 ...
) 200>/var/lock/mylockfile

3. 文件描述符模式(高級用法)

exec 200>/var/lock/mylockfile
flock -x 200
# ... 臨界區 ...
flock -u 200
exec 200>&-

關鍵參數

參數說明
-s, --shared獲取共享鎖
-x, -e, --exclusive獲取獨佔鎖(默認)
-n, --nonblock無法獲取鎖立即返回 1,不等待
-w, --timeout SEC等待超時秒數,超時返回 1
-o, --close執行命令前關閉鎖文件描述符(防止子進程繼承鎖)
-u, --unlock顯式釋放鎖(通常不需要,自動釋放)

實戰解決方案:並發執行 + 等待全部完成

#!/bin/bash
LOCK="/tmp/parallel_tasks.lock"

# 並發啟動三個任務,持有共享鎖
flock -s "$LOCK" ssh host1 "yum update -y" &
flock -s "$LOCK" ssh host2 "yum update -y" &
flock -s "$LOCK" ssh host3 "yum update -y" &

# 等待所有任務完成:獲取獨佔鎖(會阻塞直到所有共享鎖釋放)
flock -x "$LOCK" echo "All tasks completed!"

# 後續串行工作
echo "Proceeding to next stage..."

原理:三個後台任務各持有一把共享鎖,主進程嘗試獲取獨佔鎖 → 因共享/獨佔互斥 → 阻塞等待 → 三個任務結束釋放共享鎖 → 主進程獲得獨佔鎖繼續執行。

進階模式:超時保護與非阻塞檢查

# 嘗試獲取鎖,最多等 30 秒
if flock -w 30 -x "$LOCK"; then
    critical_section
else
    echo "Lock timeout, aborting" >&2
    exit 1
fi

# 非阻塞嘗試,獲取失敗直接退出
flock -n -x "$LOCK" || { echo "Another instance running"; exit 1; }

生產級模板:單實例守護腳本

#!/bin/bash
LOCKFILE="/var/run/my_daemon.lock"
exec 200>"$LOCKFILE"
flock -n -x 200 || { echo "Already running" >&2; exit 1; }

# 守護邏輯
while true; do
    do_work
    sleep 60
done

總結

  • flock 是 **Shell 級互斥鎖標準實現**,基於 `flock(2)` 系統調用,跨 Shell、跨進程有效。
  • **共享鎖解決並發執行,獨佔鎖解決串行等待**,兩者互斥特性天然構建「並發 → 同步」模式。
  • 優於臨時文件鎖:自動清理、支持超時/非阻塞、文件描述符綁定靈活、語義清晰。
  • 將 flock 納入腳本工具箱,徹底告別 sleep 猜謎與臨時文件競態。
Copyright © Windows教程網 All Rights Reserved