Код: Выделить всё
ro
Код: Выделить всё
rw
"Процесс открытия" выглядит следующим образом:
Код: Выделить всё
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.
Код: Выделить всё
int current_lock = LOCK_UN; // Initial state
void flock(int lock)
{
if (lock != current_lock) {
flock(fd, lock);
current_lock = lock;
}
}
Мой вопрос здесь о потере свойства "совместного использования" режима ro, которое зависит от особенностей реализации flock в Linux:
- Представьте себе два процесса P1 и P2, открывающие файл в ro.
- Оба пытаются перейти на LOCK_EX, если файл пуст или находится в плохом состоянии.
- P1 сначала принимает LOCK_EX, а потом исправление возвращается к LOCK_SH.
- Будет ли когда-нибудь разблокирован P2?
Код: Выделить всё
flock(fd, LOCK_UN);
flock(fd, LOCK_X); // where X is SH or EX, whatever is requested
Код: Выделить всё
// 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
Код: Выделить всё
// 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.
Я не ищу в этих вопросах ответов типа: "нужно это сделать, это работает". Я хочу также разобраться в гарантиях, которые дает Linux, чтобы написать удобную мне реализацию. Я не смог понять это должным образом после прочтения страниц руководства.
Подробнее здесь: https://stackoverflow.com/questions/784 ... ld-two-pro