2008-11-28 11 views
9

Jest to standardowe podejście do tworzenia blokad za pomocą systemu plików. Na przykład, visudo używa go:stan wyścigu we wspólnym zamkiem w pliku?

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

1) Jestem zdezorientowany, bo nie jest to sytuacja wyścigu, ale Linux używa go

2) Czy istnieje lepszy sposób na zablokowanie plików z muszli?

3) czy zamiast tego muszę używać katalogów?

Znalezione rozwiązanie: plik blokujący man.

+1

Pytania powinny być oznaczone "[rozwiązano]", wybierając odpowiedź, a nie edytując tytuł i dodając "[rozwiązany]". –

+0

problem polega na tym, że nie mogę oznaczyć własnej odpowiedzi jako "zaakceptowanej" –

+2

Nie sądzę, że twoja odpowiedź jest najlepsza, szczerze mówiąc :) –

Odpowiedz

17

Tak, rzeczywiście istnieje warunek wyścigu w przykładowym skrypcie. Możesz użyć opcji bash noclobber, aby uzyskać awaria w przypadku wyścigu, gdy inny skrypt wkrada się pomiędzy test i dotyk.

To jest opisane here. Mam zaczerpnięty krytyczne kawałek, z kilkoma adnotacji (ustalonej przez BK :):

Możliwym rozwiązaniem tego problemu jest użycie przekierowania IO oraz tryb noclobber bash, który nie będzie przekierować do istniejącego pliku . Możemy użyć coś podobnego do:

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 jest przydatny, dzięki –

+1

Dzięki! [Reposted here] (http://stackoverflow.com/a/31955862/471376). – JamesThomasMoon1979

0

wydaje się znalazłem łatwiejsze rozwiązanie: man pliku lockfile

+1

Należy pamiętać, że plik blokujący nie jest przenośny - może być niedostępny; jest częścią procmail (AFAIK). –

+0

Powłoka Linuksa jeszcze mniej :) –

+0

Powłoka jest bardziej przenośna niż procmail, o ile masz większe szanse na bash niż procmail. Mam bash na Solaris, Linux, Mac i Windows tutaj. 'lockfile' nie znajduje się na żadnym z nich. –

8

Try polecenia stada:

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

To zakończy Jeśli plik blokady jest zamknięte. Jest atomowy i będzie działał nad ostatnią wersją NFS.

Zrobiłem test. Stworzyłem plik licznik z 0 w niego i wykonywany następuje w pętli na dwóch serwerach jednocześnie 500 razy:

#!/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 

Jeden węzeł walczyła z drugą dla zamka. Kiedy oba uruchomienia zakończyły się, zawartość pliku wynosiła 1000. Próbowałem wiele razy i zawsze działa!

Uwaga: klientem NFS jest RHEL 5.2, a używany serwer to NetApp.

+0

świetny post! dziękuję – Janning

+0

Odpowiednio dobry zasięg na stadzie: w moim próbowaniu, mam go na Cygwin i Linuksie, ale nie na Solarisie ani Macu. –

+1

Czy mógłbyś wyjaśnić nieco składnię? Szczególnie zastanawiam się nad 'exec 200>" $ LOCK_FILE "'. Zrozumie to ze stronami man, ale twoja odpowiedź byłaby o wiele lepsza, gdyby wyjaśniła, co robią te linie. –

Powiązane problemy