Блокировка файлов в R через пакет flock, похоже, не работает

#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 интерфейсом, который является более надежным).