Блокировка и отсоединение файлов r/w
-
19-09-2019 - |
Вопрос
У меня есть следующая проблема.Я хочу создать хранилище сеансов на основе файловой системы, где данные каждого сеанса хранятся в простом файле с именем и идентификаторами сеанса.
Мне нужен следующий API: write(sid,data,timeout)
, read(sid,data,timeout)
, remove(sid)
где sid== имя файла, также я хочу иметь какой-то GC, который может удалять все сеансы с истекшим временем ожидания.
Довольно простая задача, если вы работаете с одним процессом, но абсолютно нетривиальная при работе с несколькими процессами или даже через NFS.
Самое простое решение, о котором я подумал, было:
write/read:
fd=open(file_name,O_CREAT | O_RDWR); // create a new file or use exsting
fcntl_lock_file(fd)
save data to fd/read data from fd
fcntl_unlock_file(fd)
close(fd)
GC:
fd=open(file_name,O_RDWR);
fcntl_lock_file(fd)
if(timed_out)
unlink(file_name)
fcntl_unlock_file(fd)
close(fd)
Самая большая проблема, что файл с отключаемым работает с именами файлов и блокировка файла работы на файл дескрипторы.Таким образом, вышесказанное не сработало бы в следующем сценарии:
GC - open,
write - open
GC - lock, unlink, unlock, close // file still exists because held by write
write - lock, write, unlock, close // file removed
У кого-нибудь есть идея, как можно решить такую проблему?Существуют ли какие-либо хитрости, позволяющие объединить блокировку файла и удаление файла или сделать операцию над файлом атомарной?
Примечания:
- Я не хочу использовать базу данных,
- Я ищу решение для Unix
- Решение должно работать со стандартными вызовами POSIX, такими как fcnl, open, close, unlink
Спасибо.
Очистка основная проблема заключается в том, что операция с файлами (имена -- unlink) должна выполняться атомарно с операцией с файловыми дескрипторами -- locking:
- открывать, отсоединять - работать с файлами
- fnctl - работа с дескрипторами
Решение
Разве это не сработало бы?
write/read:
fd=open(file_name,O_CREAT | O_RDWR); // create a new file or use exsting
fcntl_lock_file(fd)
if stat(file_name).{st_dev, st_ino} != fstat(fd).{st_dev, st_ino}
unlock, close, retry
save data to fd/read data from fd
fcntl_unlock_file(fd)
close(fd)
Если stat
сбой с EEXIST (имя файла не существует) или показывает, что текущий файл не совпадает с тем, который вы открыли, bail.