2009-02-22 12 views

Odpowiedz

57

Jaka jest różnica między lockf i fcntl:

W wielu systemach rutynowe biblioteki lockf() jest tylko nakładką na fcntl(). To znaczy, że lockf oferuje podzestaw funkcji, które wykonuje fcntl.

Source

Ale w niektórych systemach, fcntl i lockf zamki są całkowicie niezależne.

Source

Ponieważ jest zależna od implementacji, upewnij się, aby zawsze używać tej samej konwencji. Dlatego zawsze używaj lockf z obu procesów lub zawsze używaj fcntl. Istnieje duża szansa, że ​​będą wymienne, ale bezpieczniej jest używać tego samego.

Który z wybranych elementów nie ma znaczenia.


Kilka uwag na temat blokad doradczych vs obowiązkowe:

Blokowanie w Unix/Linux jest domyślnie doradczy, co oznacza inne procesy nie trzeba przestrzegać reguł blokujących, które są ustawione. Nie ma więc znaczenia, w którą stronę się zablokujesz, o ile twoje procesy kooperacji również stosują tę samą konwencję.

Linux obsługuje blokowanie obowiązkowe, ale tylko wtedy, gdy system plików jest podłączony z włączoną opcją i ustawionymi atrybutami specjalnymi pliku. Możesz użyć mount -o mand, aby zamontować system plików i ustawić atrybuty pliku g-x,g+s, aby włączyć obowiązkowe blokady, a następnie użyć fcntl lub lockf. Aby uzyskać więcej informacji na temat działania obowiązkowych blokad, zobacz here.

Należy pamiętać, że blokady są stosowane nie do pojedynczego pliku, ale do i-węzła. Oznacza to, że 2 nazwy plików wskazujące te same dane pliku będą miały ten sam status blokady.

W systemie Windows można aktywnie otwierać tylko plik, co uniemożliwi innym procesom otwarcie go całkowicie. Nawet jeśli tego chcą. Tj. Zamki są obowiązkowe. To samo dotyczy systemu Windows i blokad plików. Każdy proces z otwartym uchwytem pliku z odpowiednim dostępem może zablokować część pliku i żaden inny proces nie będzie mógł uzyskać dostępu do tej części.


Jak obowiązkowe blokad pracować w Linux:

dotyczące obowiązkowych blokad, jeśli proces blokuje regionu pliku z zamkiem odczytu, a następnie inne procesy są dozwolone czytać ale nie pisać, że region. Jeśli proces blokuje region pliku z blokadą zapisu, inne procesy nie mogą czytać ani zapisywać do pliku. Co się stanie, gdy proces nie uzyska dostępu do części pliku, zależy od tego, czy podałeś O_NONBLOCK czy nie. Jeśli ustawione jest blokowanie, będzie czekać na wykonanie operacji. Jeśli nie ustawiono blokowania, otrzymasz kod błędu EAGAIN.


NFS ostrzeżenie:

Bądź ostrożny, jeśli używasz polecenia blokujące na NFS. Zachowanie jest niezdefiniowane, a jego implementacja jest bardzo różna, niezależnie od tego, czy używa się tylko blokady lokalnej, czy do zdalnego blokowania.

+0

doskonałe wyjaśnienie, kudos !! –

+3

To już nie jest poprawne. Blokowanie plików działa na nfs 3.0, ale tylko z fcntl, nie flokiem – frankc

+8

"Ale w niektórych systemach, blokady fcntl i lockf są całkowicie niezależne" - Nie. W niektórych systemach, blokady fcntl i flock są całkowicie niezależne, jak wyjaśniono w artykule, do którego się łączysz. Jednak blokady fcntl i lockf są zawsze powiązane (tylko nie związane z flockiem). –

1

Ponieważ koduje się tylko demona, który używa go do wzajemnego wykluczania, są one równoważne, w końcu aplikacja musi być zgodna tylko z nią.

Sztuczka z mechanizmami blokowania plików ma być spójna - użyj jednego i trzymaj się go. Zmienianie ich jest złym pomysłem.

Zakładam tutaj, że system plików będzie lokalna - jeśli tak nie jest, wówczas wszystkie zakłady są wyłączone, nfs/inne systemy plików sieciowych uchwyt blokujący o różnym stopniu skuteczności (w niektórych przypadkach brak)

10

Oba interfejsy są częścią standardu POSIX, a obecnie oba interfejsy są dostępne na większości systemów (sprawdziłem tylko systemy Linux, FreeBSD, Mac OS X i Solaris). Dlatego wybierz ten, który pasuje do Twoich wymagań i używaj go.

Jedno słowo ostrożności: nie jest określone, co się dzieje, gdy jeden proces blokuje plik za pomocą fcntl, a inny za pomocą lockf. W większości systemów są to równoważne operacje (w rzeczywistości pod Linx lockf jest implementowany na górze fcntl), ale POSIX twierdzi, że ich interakcja jest nieokreślona. Jeśli więc współpracujesz z innym procesem wykorzystującym jeden z dwóch interfejsów, wybierz ten sam.

Inni napisali, że zamki mają charakter wyłącznie doradczy: jesteś odpowiedzialny za sprawdzenie, czy region jest zablokowany. Ponadto, nie używaj funkcji stdio, jeśli chcesz korzystać z funkcji blokowania.

9

główne problemy, w tym przypadku (czyli gdy „kodowania demona Linux i zastanawiasz się, który lepiej nadaje się do wykorzystania egzekwowania wzajemne wykluczanie”), powinno być:

  1. będzie zablokowana plik jest lokalny czy może być na NFS?
    • np. czy użytkownik może cię nakłonić do stworzenia i zablokowania pliku pid demona na NFS?
  2. Jak zachowa się blokada po fork, lub gdy proces demona zostanie zakończony z ekstremalnymi uprzedzeniami, np. kill -9?

Polecenia flock i fcntl zachowują się różnie w obu przypadkach.

Moja rekomendacja to użycie fcntl.Można odwołać się do File locking article on Wikipedia dla pogłębionej dyskusji na temat problemów związanych z obu rozwiązań:

Zarówno trzodę i FCNTL mieć dziwactwa, które sporadycznie puzzle programistów z innych systemów operacyjnych. Czy kłaczki działają w sieciowych systemach plików, , takich jak NFS, jest zależne od implementacji . W systemach BSD stada wywoławcze odnoszą sukcesy w operacjach typu "no-ops". W systemie Linux przed do 2.6.12 wywołania flokowe na plikach NFS działałyby tylko lokalnie. Jądro 2.6.12 i powyżej realizuje wywołania flockowe na plikach NFS przy użyciu bloków zasięgu POSIX. Te blokady będą widoczne dla innych klientów NFS z serii , które implementują blokady zamkówfcntl()/POSIX. 1 Zablokowanie aktualizacji i obniżenie wersji powoduje zwolnienie starej blokady przed zastosowaniem nowej blokady. Jeśli aplikacja obniży zastrzeżenie do udostępnionej blokady, podczas gdy inna aplikacja zostanie zablokowana czekając na wyłączną blokadę , ta ostatnia aplikacja otrzyma wyłączny blokadę, a pierwsza aplikacja zostanie zablokowana. Wszystkie zamki FCNTL związane z plikiem dla danego procesu są usuwane po każdy deskryptor pliku dla tego pliku jest zamknięty przez ten proces, nawet jeśli blokada nigdy nie została wezwana do tego pliku deskryptora. Ponadto, blokady fcntl nie są dziedziczone przez proces potomny. Szczegółowa semantyka fcntl jest szczególnie kłopotliwa dla aplikacji, które wywołują biblioteki podprogramów, które mogą mieć dostęp do plików.

6

Natknąłem się na problem podczas korzystania z fcntl i flock ostatnio, że czułem, że powinienem zgłosić się tutaj, ponieważ poszukiwanie obu terminów pokazuje tę stronę w pobliżu góry na obu.

Zalecane zamki BSD, jak wspomniano powyżej, są doradztwo. Dla tych, którzy nie znają OSX (darwin) jest BSD. Należy o tym pamiętać przy otwieraniu pliku, do którego należy pisać.

Aby użyć fcntl/flock, musisz najpierw otworzyć plik i uzyskać jego ID. Jednakże, jeśli otworzyłeś plik z "w", plik natychmiast zostanie wyzerowany z. Jeśli twój proces nie zdoła uzyskać blokady, ponieważ plik jest używany gdzie indziej, najprawdopodobniej zwróci, pozostawiając plik jako 0kb. Proces, który miał blokadę, sprawi, że plik zniknie spod niego, zwykle następują katastrofalne wyniki.

Aby zaradzić tej sytuacji, podczas korzystania z funkcji blokowania plików, nigdy otwórz plik "w", ale zamiast tego otwórz "a", aby dołączyć. Następnie, jeśli blokada zostanie pomyślnie uzyskana, możesz bezpiecznie wyczyścić plik, tak jak "w", tj. :

fseek (UCHWYTPLIKU, 0, SEEK_SET); // przejść na początek

ftruncate fileno (((FILE *) filehandle), 0); // jasne to się

To był nieprzyjemna lekcja dla mnie.

+1

Przypuszczam, że chodziło o otwarcie pliku z '' r + "' (O_RDWR) zamiast '" a "' (O_APPEND) - i oczywiście bez 'O_TRUNC' jako' 'w" ' – sebulba

Powiązane problemy