Как я могу сделать неблокирующий запрос на эксклюзивную блокировку, используя File # flock?
Почему нетт Руби# Флок файла работать как положено, когда предпринимаются отдельные попытки заблокировать файл? Блокировка файла в блоке не является правильным решением для этой проблемы, потому что цель состоит в том, чтобы показать поведение блокировки настойкий замки. Использование File # flock внутри блока снимает блокировку при выходе из блока, поэтому он неt правильно продемонстрировать проблему.
Файл # flock дает сбой различными способами, особенно при запросе неблокирующей блокировки. Вот несколько примеров.
Неудачные примеры с файлом # flockБесконечное ожидание при использовании нескольких эксклюзивных блокировок, так как #flock не делаетt предоставить способ для тайм-аута запроса блокировки.
# First lock succeeds.
f1 = File.open('foo', File::RDWR|File::CREAT, 0644)
f1.flock(File::LOCK_EX)
# => 0
# This never returns.
f2 = File.open('foo', File::RDWR|File::CREAT, 0644)
f2.flock(File::LOCK_EX)
Запрос неблокирующей блокировки, когда файл является исключительно заблокированным, приводит к недопустимому исключению аргумента.
f1 = File.open('foo', File::RDWR|File::CREAT, 0644)
f1.flock(File::LOCK_EX)
# => 0
f2 = File.open('foo', File::RDWR|File::CREAT, 0644)
f2.flock(File::LOCK_NB)
# => Errno::EINVAL: Invalid argument - foo
В документации написано, что #flock "Блокирует или разблокирует файл в соответствии с lock_constant (логическое значение или значения в таблице ниже). " Тем не менее, логическое ИЛИ поднимаетErrno::EINVAL
или жеErrno::EBADF
в зависимости от платформы.
f1 = File.open('foo', File::RDWR|File::CREAT, 0644)
f1.flock(File::LOCK_EX)
# => 0
f2 = File.open('foo', File::RDWR|File::CREAT, 0644)
f2.flock(File::LOCK_NB || File::LOCK_EX)
# => Errno::EINVAL: Invalid argument - foo
Собственный файл # flock Solution PreferredХотя можно использоватьМодуль тайм-аута подниматьTimeout::Error
при невозможности получить эксклюзивную блокировку кажется, что File # flock должен иметь возможность решить эту проблему изначально. Итак, как на самом деле можно запрашивать эксклюзивную блокировку без блокировки?