2010-10-10 1 views
2

Модуль fcnt Python предоставляет метод, называемый [flock] [1], для доказанной блокировки файлов. Это описание гласит:Функция fcntl.flock python обеспечивает блокировку доступа к файлу уровня потока?

Выполните операции блокировки цит на файл дескриптора дескрипторе (файловые объекты обеспечения метод fileno() принимается в качестве хорошо). Подробную информацию см. В руководстве по установке Unix (2) . (. В некоторых системах, эта функция эмулируются с использованием Fcntl())

Глядя страницу Linux человек для стада, оно относится только пересечь процесс блокировки, например:

Вызов для flock() может блокироваться, если несовместимая блокировка удерживается другим процессом . Чтобы сделать неблокирующий запрос , включите LOCK_NB (ORing) с любой из вышеперечисленных операций.

Итак, мой вопрос: будет ли flock() также обеспечивать надежную блокировку потоков и блокировать несколько потоков в рамках одного процесса, а также потоков из разных процессов?

[1]: http://docs.python.org/library/fcntl.html#fcntl.flockfunction эмулируется с помощью Fcntl())

ответ

4

flock замки не заботитесь о потоках - на самом деле, они не заботятся о процессах, либо.. Если вы возьмете один и тот же дескриптор файла в двух процессах (унаследованных через fork), либо процесс блокировки файла с этим 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-интерфейсами на уровне ядра. По большей части, если syscall-документы обрабатывают поведение дочернего/родительского поведения, то они будут сохраняться для потоков.

Конечно, вы можете (и, вероятно, должны) проверить это поведение самостоятельно.

+4

Вы говорите круглым способом, что для правильного использования блокировки вам нужно получить различный дескриптор файла в каждом контексте? –

Смежные вопросы