2015-09-15 2 views
4

У меня есть два (или более) процесса python и вы хотите создать концепцию, аналогичную exclusion mutex для общего ресурса. «Общий ресурс» в этом случае является каталогом. Как я могу легко/стандартно/etc реализовать мьютекс? Скрытый файл .lock, который каждый процесс согласен проверить и, если существует, добавляет свой PID в новую строку, а затем выдает свой PID, когда у них есть доступ к файлу?Как заблокировать каталог между процессами python в linux?

Я просто хочу очистить каталог и убедиться, что ни один другой процесс не пытается его прочитать или написать, пока я его очищаю.

Существует ли стандартный способ linux? Может быть, что-то, что я могу выполнить с помощью строки оболочки из python?

+0

Вы хотите удостовериться, что никакой другой процесс или никакой другой процесс _Python_ не может r/w из этого каталога? –

+0

В идеале никаких других процессов, но поскольку все, что я пишу прямо сейчас, находится в python, просто процессы Python в порядке. Таким образом, я могу контролировать то, что они ищут, если этот маршрут необходим. Я надеюсь найти готовое решение для того, что кажется общей потребностью, хотя это не относится к python или моему приложению. – tarabyte

ответ

3

Linux

Есть два стандартных типа блокировки в Linux: advisory locking (указанные в POSIX) и mandatory locking (Linux, специфичные).

Однако оба они могут применяться только к файлам, но не к каталогам. Так что да, вам нужен файл блокировки. Предполагается, что все пользователи должны знать об заблокированном файле и получить блокировку перед доступом к каталогу. Следовательно, обязательная блокировка здесь не поможет, и вам нужна консультативная блокировка.

Есть три вида консультативных замков файлов в Linux:

  • flock(2) (указан в POSIX);
  • Блокировка записи POSIX, см. Раздел «Секретная блокировка отчетов» в fcntl(2), а также обертка lockf(3) (оба указаны в POSIX);
  • Открыть файл описания замков, см. fcntl(2) (Linux-specific, доступно в последних версиях ядра).

Python

В Python flock(), lockf() и fcntl() функции доступны через fcntl модуля. Также есть модуль flock, который добавляет поддержку контекстного менеджера функции fcntl.flock.

Вот пример:

import flock 

with open('/my/dir/lockfile', 'w') as fp: 
    with flock.Flock(fp, flock.LOCK_EX) as lock: 
     pass # exclusive lock is acquired here 

PS.

При таком подходе вы не можете предотвратить случайный процесс доступа к вашему каталогу, если он не знает о вашем файле блокировки. Вероятно, возможно реализовать файловую систему с использованием FUSE, которая будет поддерживать обязательные блокировки каталогов, но я не знаю об этих реализациях.

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