flock
блокировки не заботятся о потоках - фактически, они также не заботятся о процессах.Если вы берете один и тот же файловый дескриптор в двух процессах (унаследованных через форк), любой процесс, блокирующий файл с помощью этого FD, получит блокировку для обоих процессов.Другими словами, в следующем коде оба вызова flock
вернут успех: дочерний процесс блокирует файл, а затем родительский процесс получает одну и ту же блокировку, а не блокировку, потому что они оба одинаковыFD.
import fcntl, time, os
f = open("testfile", "w+")
print "Locking..."
fcntl.flock(f.fileno(), fcntl.LOCK_EX)
print "locked"
fcntl.flock(f.fileno(), fcntl.LOCK_UN)
if os.fork() == 0:
# We're in the child process, and we have an inherited copy of the fd.
# Lock the file.
print "Child process locking..."
fcntl.flock(f.fileno(), fcntl.LOCK_EX)
print "Child process locked..."
time.sleep(1000)
else:
# We're in the parent. Give the child process a moment to lock the file.
time.sleep(0.5)
print "Parent process locking..."
fcntl.flock(f.fileno(), fcntl.LOCK_EX)
print "Parent process locked"
time.sleep(1000)
На одном и том же токене, если вы заблокируете один и тот же файл дважды, но с разными файловыми дескрипторами, блокировки будут блокировать друг друга - независимо от того, находитесь ли вы в одном процессе илита же нить.Смотрите flock (2): If a process uses open(2) (or similar) to obtain more than one descriptor for the same file, these descriptors are treated independently by flock(). An attempt to lock the file using one of these file descriptors may be denied by a lock that the calling process has already placed via another descriptor.
Полезно помнить, что для ядра Linux процессы и потоки, по сути, одно и то же, и, как правило, они обрабатываются API-интерфейсами уровня ядра одинаково.По большей части, если системный вызов документирует поведение дочернего / родительского процесса, то же самое относится и к потокам.
Конечно, вы можете (и, вероятно, должны) проверить это поведение самостоятельно.