W systemie operacyjnym opartym na Debianie (Ubuntu, Squeeze Debiana) używam Pythona (2.7, 3.2) fcntl, aby zablokować plik. Jak rozumiem z tego, co przeczytałem, fnctl.flock blokuje plik w taki sposób, że wyjątek zostanie zgłoszony, jeśli inny klient chce zablokować ten sam plik.Python fcntl nie blokuje zgodnie z oczekiwaniami
Zbudowałem mały przykład, który spodziewałbym się rzucić excepiton, odkąd pierwszy zablokować plik, a następnie, bezpośrednio po, staram się zablokować go ponownie:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import fcntl
fcntl.flock(open('/tmp/locktest', 'r'), fcntl.LOCK_EX)
try:
fcntl.flock(open('/tmp/locktest', 'r'), fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
print("can't immediately write-lock the file ($!), blocking ...")
else:
print("No error")
ale przykład tylko drukuje "Brak błędu".
Jeśli podzielę ten kod maksymalnie na dwa klienty działające w tym samym czasie (jedno blokowanie, a następnie czekanie, a drugi próbuje zablokować po tym, jak pierwsza blokada jest już aktywna), otrzymam to samo zachowanie - brak efektu.
Jakie jest wytłumaczenie tego zachowania?
EDIT:
Zmiany wymagane przez nightcracker, ta wersja drukuje także "Brak błędu", chociaż nie spodziewałbym się, że:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import fcntl
import time
fcntl.flock(open('/tmp/locktest', 'w'), fcntl.LOCK_EX | fcntl.LOCK_NB)
try:
fcntl.flock(open('/tmp/locktest', 'w'), fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
print("can't immediately write-lock the file ($!), blocking ...")
else:
print("No error")
Istnieje [haczyk dotyczący blokad plików w ramach tego samego procesu] (http://0pointer.de/blog/projects/locking.html). W ramach jednego procesu wątki będą dzielić blokadę pliku. – bouke