Если все, что вам нужно, это блокировка read , то в вашем коде есть только незначительная ошибка.Вполне возможно получить блокировку чтения в каталоге.
Вам необходимо изменить функцию __exit__
, чтобы использовать os.close()
, чтобы закрыть дескриптор файла;дескриптор файла - это просто целое число, и у целых чисел нет метода .close()
:
def __exit__(self, exc_type, exc_val, exc_tb):
os.close(self.dir_fd)
Обычное замешательство для людей, которые думают, что вы не можете, это те, кто пытался использовать функцию open()
.Python не позволит вам открыть узел каталога с этой функцией, потому что нет смысла создавать объект файла Python для каталога.Или, возможно, существует предположение, что вы хотели, чтобы ОС обеспечивала принудительный доступ к каталогу через блокировку (в отличие от консультативной блокировки, которую кооперативный набор процессов соглашается получить в первую очередь перед попыткой доступа).
Так что нет, в коде нет ничего плохого, если все, что вам нужно, это консультативная блокировка, и хорошо, если это работает только в Linux.
Я бы отбросил отличие directory
от кода.Блокировка будет работать на любом пути, к которому у вас есть доступ для чтения.Это не только для каталогов.
Недостатком блокировки каталога является то, что это не дает вам места для хранения метаданных блокировки.В то время как lsof
может дать вам PID текущего владельца блокировки, вы можете захотеть передать некоторую другую информацию с помощью блокировки, чтобы помочь устранить неполадки или автоматизировать взлом блокировки.Файл .lock
или символическая ссылка позволят вам записать дополнительную информацию.Например, Mercurial создаст символическую ссылку с именем хоста, идентификатором пространства имен PID (только для Linux) и PID в целевом имени;Вы можете создать такую символическую ссылку атомарно, в то время как запись этих данных в файл потребует создания файла с временным именем и последующим переименованием.