Мне нужно заблокировать файл для записи в Python. Он будет доступен сразу из нескольких процессов Python. Я нашел некоторые решения в Интернете, но большинство из них не подходят для моих целей, поскольку они часто основаны только на Unix или Windows.
python
file-locking
Эван Фосмарк
источник
источник
Здесь есть кроссплатформенный модуль блокировки файлов: Portalocker
Хотя, как говорит Кевин, запись в файл из нескольких процессов одновременно - это то, чего вы хотите избежать, если это вообще возможно.
Если вы можете поместить вашу проблему в базу данных, вы можете использовать SQLite. Он поддерживает одновременный доступ и обрабатывает собственную блокировку.
источник
Другие решения ссылаются на множество внешних кодовых баз. Если вы предпочитаете сделать это самостоятельно, вот код для кроссплатформенного решения, использующего соответствующие инструменты блокировки файлов в системах Linux / DOS.
Теперь
AtomicOpen
можно использовать вwith
блоке, где обычно используетсяopen
оператор.ПРЕДУПРЕЖДЕНИЕ. Если запуск в Windows и Python завершается сбоем до вызова exit , я не уверен, каково будет поведение блокировки.
ВНИМАНИЕ: Блокировка, представленная здесь, носит рекомендательный, а не абсолютный характер. Все потенциально конкурирующие процессы должны использовать класс «AtomicOpen».
источник
unlock_file
файл на linux не должен вызыватьfcntl
снова сLOCK_UN
флагом?__exit__
васclose
за пределами замка послеunlock_file
. Я считаю, что среда выполнения может сбрасывать (т.е. записывать) данные во времяclose
. Я полагаю, что нужноflush
иfsync
под замком убедиться, что никакие дополнительные данные не записываются за пределы замка во времяclose
.flush
иfsync
. Я добавил две предложенные вами строки перед звонкомunlock
. Я повторно проверил, и состояние гонки, кажется, решено.Я предпочитаю lockfile - Платформо-независимая блокировка файлов
источник
Я искал несколько решений, чтобы сделать это, и мой выбор был oslo.concurrency
Это мощный и относительно хорошо документированный. Он основан на крепежных деталях.
Другие решения:
источник
filelock
(последний выпущен: 18 мая 2019 во время комментария)Блокировка зависит от платформы и устройства, но обычно у вас есть несколько вариантов:
Для всех этих методов вам придется использовать технику спин-блокировки (повторная попытка сбоя) для получения и тестирования блокировки. Это оставляет небольшое окно для несинхронизации, но обычно оно достаточно маленькое, чтобы не быть серьезной проблемой.
Если вы ищете решение, которое является кроссплатформенным, то вам лучше подключиться к другой системе через какой-то другой механизм (следующая лучшая вещь - это метод NFS, описанный выше).
Обратите внимание, что на sqlite распространяются те же ограничения на NFS, что и на обычные файлы, поэтому вы не можете писать в базу данных sqlite на сетевом ресурсе и получать синхронизацию бесплатно.
источник
os.rename
теперь в Win32 атомарный начиная с Python 3.3: bugs.python.org/issue8828Координация доступа к одному файлу на уровне ОС чревата всевозможными проблемами, которые вы, вероятно, не хотите решать.
Лучше всего иметь отдельный процесс, который координирует доступ для чтения / записи к этому файлу.
источник
flock
эта. Подход «накатить свои собственные мьютексы и процесс демона для управления ими» кажется довольно экстремальным и сложным подходом для решения ... проблемы, о которой вы на самом деле не говорили нам, а просто пугающе предположили, что она существует.Блокировка файла обычно является операцией, специфичной для платформы, поэтому вам может потребоваться возможность запуска в разных операционных системах. Например:
источник
Я работал над такой ситуацией, когда я запускаю несколько копий одной и той же программы из одного каталога / папки и регистрирую ошибки. Мой подход состоял в том, чтобы записать «файл блокировки» на диск перед открытием файла журнала. Программа проверяет наличие «файла блокировки», прежде чем продолжить, и ждет его очереди, если «файл блокировки» существует.
Вот код:
РЕДАКТИРОВАТЬ --- Подумав над комментариями о устаревших блокировках выше, я отредактировал код, добавив проверку на устаревание "файла блокировки". Время выполнения нескольких тысяч итераций этой функции в моей системе дало в среднем 0,002066 ... секунд до этого:
сразу после:
поэтому я подумал, что начну с 5-кратного увеличения этой суммы, чтобы указывать на устаревание и отслеживать ситуацию на наличие проблем.
Кроме того, когда я работал с синхронизацией, я понял, что у меня есть немного кода, который на самом деле не был необходим:
который у меня был сразу после оператора open, поэтому я удалил его в этом редактировании.
источник
Чтобы добавить ответ Эвана Фоссмарка , вот пример использования filelock :
Любой код внутри
with lock:
блока является поточно-ориентированным, что означает, что он будет завершен до того, как другой процесс получит доступ к файлу.источник
сценарий такова: пользователь запрашивает файл , чтобы сделать что - то. Затем, если пользователь снова отправляет тот же запрос, он информирует пользователя о том, что второй запрос не выполнен, пока первый запрос не завершится. Вот почему я использую механизм блокировки для решения этой проблемы.
Вот мой рабочий код:
источник
Я нашел простую и отработанную (!) Реализацию из grizzled-python.
Простое использование os.open (..., O_EXCL) + os.close () не работает на окнах.
источник
Вы можете найти pylocker очень полезным. Его можно использовать для блокировки файла или для механизмов блокировки в целом, и к нему можно получить доступ сразу из нескольких процессов Python.
Если вы просто хотите заблокировать файл, вот как это работает:
источник