File-Descriptors

羊群似乎沒有工作

  • December 15, 2017

我最近一直在嘗試為一個小項目創建一個 shell 腳本,但由於某種原因,該flock命令對我來說不能正常工作。每當我以原子方式在子shell中呼叫它並將其置於後台時,其他程序似乎都能夠讀取/寫入鎖定的文件。

重擊會話:

guest@guest ~ $ touch ./temp
guest@guest ~ $ ( flock -x 3 && sleep 99999999999; ) 3>./temp &
[1] 22874
guest@guest ~ $ cat ./temp 
guest@guest ~ $ echo this is a test >./temp 
guest@guest ~ $ cat ./temp 
this is a test
guest@guest ~ $ jobs
[1]+  Running                 ( flock -x 3 && sleep 99999999999 ) 3>./temp &
guest@guest ~ $ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

我覺得我可能遺漏了一些與“flock”程序內部相關的非常簡單的東西,但不知道它可能是什麼。

flock做諮詢鎖定,這是一種合作鎖定方案。這意味著如果您不合作,您將能夠覆蓋鎖定。您通過在執行操作之前請求鎖定來配合,然後在完成後釋放鎖定。它是受鎖保護的操作,而不是(必然)鎖文件本身。

從我係統上flock(2)手冊:

諮詢鎖允許合作程序對文件執行一致的操作,但不保證一致性(即,程序仍可以在不使用諮詢鎖的情況下訪問文件,這可能會導致不一致)。

考慮這個腳本:

#!/bin/sh

( flock -x 9 || exit 1
 echo '1: Locking for 5 secs'; sleep 5; echo '1: Done' ) 9&gt;/tmp/lock &

sleep 1
echo '2: Will now attempt to get lock'

( flock -x 9 || exit 1
 echo '2: Got lock' ) 9&gt;/tmp/lock

# Since the second flock call only performs one operation, the whole last 
# subshell may be replaced by just
#    flock -x /tmp/lock -c echo '2: Got lock'
#
#  (-x and -c are not needed, a lock is exclusive ("write lock")
#   unless -s is used to create a shared lock ("read lock"),
#   and the -c is optional)

輸出:

1: Locking for 5 secs
2: Will now attempt to get lock
1: Done
2: Got lock

您可以看到鎖是由後台程序獲取的,並且其他flock呼叫必須等待它被釋放才能鎖定它。

另請注意,鎖定文件在這裡不受保護,它是echo子shell 中的操作,保證是獨占的。特別是,鎖定文件不受對其進行寫入或讀取的不合作程序的保護。

這意味著每個flock子shell,通過在這個例子中鎖定/tmp/lock,保證操作(在文件或其他共享數據資源上)不會與來自任何其他使用flockwith/tmp/lock作為鎖定文件的程序的衝突操作混合。

為了說明上面的最後一段,盡可能同時在兩個不同的終端(可能稍微增加睡眠時間)中執行我的腳本,並驗證兩個競爭腳本是否適當地獲取了鎖(相互等待)。由於在後台程序中請求一個鎖,這意味著當同時執行腳本的兩個實例時,可能會按照腳本中指定的順序不按順序獲取鎖。

在您的範例中,互動式外殼不與鎖定機制合作。這就是為什麼即使鎖由後台子shell 持有,您也可以讀取和寫入文件的原因。

另請注意,並非所有文件系統都可能支持文件鎖定flock(或其等效的 C 庫,flock())。例如,網路文件系統 AFS 和 NFS 在這方面可能存在問題。請參閱https://en.wikipedia.org/wiki/File_locking#Problems

引用自:https://unix.stackexchange.com/questions/388026