2008-11-28 60 views
9

這是使用文件系統創建鎖的標準方法。例如,visudo命令使用它:通用鎖定文件中的競態條件?

[ -f ".lock" ] && exit 1 
touch .lock 
# do something 
rm .lock 

1)我很困惑,因爲在那裏是一個競爭條件,但Linux使用它

2)是否有更好的辦法從殼鎖定的文件?

3)或者我必須使用目錄嗎?

找到解決方案:man lockfile。

+1

問題應該選擇一個答案,而不是通過編輯標題並添加「[解決]」來標記「[解決]」。 – 2008-11-28 12:35:21

+0

問題是,我不能標記自己的答案爲「接受」 – 2008-12-12 10:46:06

+2

我不認爲你的回答是最好的,坦率地說:) – 2011-02-04 11:27:51

回答

17

是的,樣本腳本確實存在競爭條件。您可以使用bash的noclobber選項,以便在比賽中獲得失敗,當不同的腳本潛入測試和觸摸之間時。

它被描述爲here。我摘錄的關鍵部分,與一對夫婦的註釋(由BK前綴:):

一個可能的解決方案是使用IO重定向和bash的noclobber選項模式,這將不會重定向到一個現有的文件。我們可以用類似於:

if (set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null; 
then 
    # BK: this will cause the lock file to be deleted in case of other exit 
    trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT 

    # critical-section BK: (the protected bit) 

    rm -f "$lockfile" 
    trap - INT TERM EXIT 
else 
    echo "Failed to acquire lockfile: $lockfile." 
    echo "Held by $(cat $lockfile)" 
fi 
+0

noclobber是有用的,謝謝 – 2011-02-18 17:23:36

0

好像我已經找到了一個簡單的解決方案:人鎖定文件

8

嘗試羊羣命令:

exec 200>"$LOCK_FILE" 
flock -e -n 200 || exit 1 

它將退出,如果鎖定文件被鎖住了。它是原子的,它可以在最近版本的NFS上運行。

我做了一個測試。我在它創造了0計數器文件,並在一個循環中執行以下上同時兩個服務器500倍:

#!/bin/bash 

exec 200>/nfs/mount/testlock 
flock -e 200 

NO=`cat /nfs/mount/counter` 
echo "$NO" 
let NO=NO+1 
echo "$NO" > /nfs/mount/counter 

一個節點與其他戰鬥的鎖。當兩次運行完成文件內容爲1000.我已經嘗試了多次,它始終工作!

注意:NFS客戶端是RHEL 5.2,使用的服務器是NetApp。