`Flock` в Linux: изменение с `LOCK_EX` на `LOCK_SH` и наоборот: будут ли два процесса блокировать друг друга?Linux

Ответить Пред. темаСлед. тема
Anonymous
 `Flock` в Linux: изменение с `LOCK_EX` на `LOCK_SH` и наоборот: будут ли два процесса блокировать друг друга?

Сообщение Anonymous »

(Linux) Мне нужно открыть файл только для чтения () или чтение-запись () по желанию пользователя. Беру LOCK_SH и/или LOCK_EX в соответствии с режимом как обычно. Но реализация выполняет некоторый контроль очистки: если файл находится в плохом состоянии, мы берем (временно) LOCK_EX, исправляем файл, а затем возвращаемся к LOCK_SH, если мы находимся в ro< /code>.
"Процесс открытия" выглядит следующим образом:

Код: Выделить всё

   int fd = open(blablabla); // with O_CREAT.
_flock(fd, rw_mode ? LOCK_EX : LOCK_SH);

if (/* file is empty */) {
_flock(LOCK_EX);
ftruncate(fd, /* right size */);
}

if (/* file is in a bad state */) {
_flock(fd, LOCK_EX);

if (/* file is in a bad state */)
fix_file(fd);
}

if (!rw_mode)
_flock(fd, LOCK_SH); // If I promoted from SH to EX, I insist in going back to SH.
где _flock реализован как:

Код: Выделить всё

int current_lock = LOCK_UN; // Initial state

void flock(int lock)
{
if (lock != current_lock) {
flock(fd, lock);
current_lock = lock;
}
}
ПРИМЕЧАНИЕ. О ftruncate. После получения LOCK_EX мне следует проверить, пуст ли файл, прежде чем выполнять ftruncate (кто-то мог уже взять блокировку до меня и изменить ее размер), но в моем случае я не против измените размер еще раз, потому что размер будет таким же, и я предпочитаю общий случай, то есть отсутствие параллелизма. Так что для меня это нормально и проще настоять на усечении файла.
Мой вопрос здесь о потере свойства "совместного использования" режима ro, которое зависит от особенностей реализации flock в Linux:
  • Представьте себе два процесса P1 и P2, открывающие файл в ro.
  • Оба пытаются перейти на LOCK_EX, если файл пуст или находится в плохом состоянии.
  • P1 сначала принимает LOCK_EX, а потом исправление возвращается к LOCK_SH.
  • Будет ли когда-нибудь разблокирован P2?
Если Linux реализует "смена замка" как будто:

Код: Выделить всё

flock(fd, LOCK_UN);
flock(fd, LOCK_X); // where X is SH or EX, whatever is requested
и если Linux будет соблюдать «порядок запроса» блокировок, то я думаю, что P2 будет прогрессировать:

Код: Выделить всё

// P1                    // P2
LOCK_SH
LOCK_SH
LOCK_UN
LOCK_UN
LOCK_EX
// requested LOCK_EX
do_fix();
LOCK_UN
LOCK_EX
// requested LOCK_SH
LOCK_UN
LOCK_SH
LOCK_SH
и после процесса открытия они смогут читать параллельно. Без этого неявного LOCK_UN в середине ни один из них не будет развиваться, верно?

Код: Выделить всё

// P1                 // P2
LOCK_SH
LOCK_SH
... no one can take a LOCK_EX at this point because they deadlock? ...
... or is kernel smart enough to know that both wants to leave the shared lock? ...
... and allow at least P1 to progress? In which case P2 won't progress I think ...
... until P1 closes the file. There is no parallelism but there's progress.
Другими словами, я хочу точно понимать, какие гарантии дает flock, особенно с точки зрения изменений режима блокировки, чтобы я мог рассуждать и реализовать открываю процесс так, как мне удобно.
Я не ищу в этих вопросах ответов типа: "нужно это сделать, это работает". Я хочу также разобраться в гарантиях, которые дает Linux, чтобы написать удобную мне реализацию. Я не смог понять это должным образом после прочтения страниц руководства.

Подробнее здесь: https://stackoverflow.com/questions/784 ... ld-two-pro
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Linux»