#r #file-locking #flock
#r #блокировка файла #flock
Вопрос:
Я использую R 3.5.3 под Ubuntu 18.04.2 LTS с файловой системой ext4 на AWS.
Кажется, я не могу заставить блокировку файлов работать так, как мне кажется, она должна работать. Вот повторный:
library(flock)
l1 <- lock("temp.txt", exclusive = TRUE)
# I expect this to fail but it doesn't
l2 <- lock("temp.txt", exclusive = TRUE)
# expect TRUE. Ok!
is.locked(l1)
# expect FALSE, but is TRUE
is.locked(l2)
unlock(l1)
# expect FALSE but is TRUE
is.locked(l1)
unlock(l2)
# expect FALSE but is TRUE
is.locked(l2)
Итак, flock сломан, не поддерживается в этой файловой системе, или я делаю это неправильно?
Спасибо
Ответ №1:
Он предназначен для блокировки процессов в «кластере» с использованием parallel
пакета. Например:
mclapply(1:10,
function(v){
l1 = lock("lock.txt")
v*2
Sys.sleep(1)
unlock(l1)
return(v*2)},
mc.cores=8)
выполнение займет около 10 секунд, потому что каждая итерация должна ждать, пока она сможет получить блокировку файла, и она заблокирована во время 1-секундного ожидания, а другой процесс ожидает. Если вместо этого я делаю:
mclapply(1:10,
function(v){
l1 = lock("lock.txt")
v*2
unlock(l1)
Sys.sleep(1)
return(v*2)},
mc.cores=8)
если блокировка выполняется перед переходом в спящий режим, то она выполняется примерно за 1 секунду, поскольку большую часть времени процессы могут продолжаться свободно.
Итак, используйте lock
внутренние parallel
выполняемые части, чтобы обеспечить эксклюзивный доступ к общему ресурсу. Я не уверен, что это имеет смысл внутри одного потока R-кода. Отдельный поток всегда сможет получить блокировку файла. Семантика «is.locked.by.this.process», поэтому вы получаете TRUE во второй раз. Не уверен, что это объясняет поведение is.locked
, но я не уверен, что тестирование того, заблокировано ли что-либо, в любом случае является хорошей практикой — либо получите блокировку и продолжайте, либо разблокируйте удерживаемую блокировку…
Комментарии:
1. Примечание:
is.locked
не проверяет, действительно ли файл заблокирован, он просматривает только объект, который вы передаете, а не файл, и этот объект всегда будет возвращатьсяTRUE
, несмотря ни на что. Аналогично,unlock
фактически невозможно разблокировать файл в целом, он может разблокировать только дескриптор, созданный вами с помощьюlock
, и он разблокирует все блокировки файла, а не только ту, которую вы передаете. Итак, это все просто ошибки в пакете (и он использует устаревшие блокировки POSIX на уровне записей черезfcntl
, которые считаются действительно плохим дизайном и были замененыflock
интерфейсом, который является более надежным).