Разблокировка и удаление файлов в качестве одной операции

StackOverflow https://stackoverflow.com/questions/1932993

  •  20-09-2019
  •  | 
  •  

Вопрос

Обратите внимание, что это не дублирует Файл R/W блокировка и Unlink. Анкет (Разница - Платформа. Операции таких файлов, как блокировка и удаление, имеют совершенно разные семантики, поэтому сульция была бы другой).

У меня есть следующая проблема. Я хочу создать хранилище сеанса на основе файловой системы, где данные каждого сеанса хранятся в простом файле с идентификаторами сеанса.

Я хочу подписаться на API: write(sid,data,timeout), read(sid,data,timeout), remove(sid)Где SID == Имя файла, также я хочу иметь какой-то GC, который может удалить все сеансы времени.

Довольно простая задача, если вы работаете с одним процессом, но абсолютно не тривиально при работе с несколькими процессами или даже с общими папками.

Самое простое решение, о котором я думал, было:

write/read:
   hanlde=CreateFile
   LockFile(handle)
   read/write data
   UnlockFile(handle)
   CloseHanlde(handle)

GC (for each file in directory)
   hanlde=CreateFile
   LockFile(handle)
   check if timeout occured
     DeleteFile
   UnlockFile(handle)
   CloseHanlde(handle)

Но я не могу позвонить DeleteFile В открытом заблокированном файле (в отличие от UNIX, где блокировка файлов не является обязательной, а UNLINK разрешается для открытых файлов.

Но если я положу DeleteFile Вне может произойти плохое сценарий петли.

GC - CreateFile/LockFile/Unlock/CloseHandle,
write - oCreateFile/LockFile/WriteUpdatedData/Unlock/CloseHandle
GC - DeleteFile

У кого -нибудь есть идея, как может быть решена такая проблема? Существуют ли какие -либо хитрости, которые позволяют объединить блокировку файлов и удаление файлов или выполнять операцию в файле Atomic (WIN32)?

Заметки:

  • Я не хочу использовать базу данных,
  • Я ищу решение для API Win32 для NT 5.01 и выше

Спасибо.

Это было полезно?

Решение

Я не очень понимаю, как это должно работать. Однако удаление файла, открытого другим процессом, возможно. Процесс, который создает файл, должен использовать флаг file_share_delete для аргумента dwsharemode of createfile (). Последующий вызов deletefile () будет успешным. Файл фактически не удаляется из файловой системы, пока последняя ручка на нем не будет закрыта.

Другие советы

В настоящее время у вас есть данные в записи, которые позволяют GC определять, будет ли запись истечена. Как насчет того, чтобы расширить эту информацию о домашнем хозяйстве с помощью флага "ToolateWealReadyTimeditOut".

 GC sets TooLateWeAlreadyTimedItOut = true
 Release lock
    <== writer comes in here, sees the "TooLate" flag and so does not write
 GC deletes

Другими словами, мы используем своего рода оптимистичный подход блокировки. Это требует некоторой дополнительной сложности в писателе, но теперь вы не зависите от каких-либо морщин OS-специфического.

Мне не ясно, что происходит в случае:

 GC checks timeout
 GC deletes
 Writer attempts write, and finds no file ...

Все, что вы запланировали для этого случая, также может быть использовано в случае «Toolate»

Отредактировано, чтобы добавить:

Вы сказали, что для этой последовательности действительно:

 GC Deletes
 (Very slightly later) Writer attempts a write, sees no file, creates a new one

Автор может рассматривать флаг «Toolate» как идентичный этому случаю. Это просто создает новый Файл, с другим именем, используйте номер версии в качестве следующей части его имени. Открытие файла сеанса в первый раз требует поиска в каталоге, но затем вы можете спрятать последнее имя в сеансе.

Это предполагает, что для данного сеанса может быть только один поток для писателей, или что мы можем опосредовать между двумя ветками писателя, создающим файл, но это должно быть верно для вашего простого дела GC/писателя.

Для Windows вы можете использовать File_flag_delete_on_close Возможность CreateFile - это приведет к удалению файла при закрытии ручки. Но я не уверен, что это удовлетворяет вашей семантике (потому что я не верю, что вы можете очистить атрибут Delete-on-Close.

Вот еще одна мысль. Как насчет переименования файла, прежде чем удалить его? Вы просто не можете закрыть окно, в котором появляется запись после того, как решил удалить файл, но что, если вы переименуете файл перед тем, как его удалить? Затем, когда появится запись, это увидит, что файл сеанса не существует, и воссоздает его.

Ключевая вещь, которую следует помнить, это то, что вы просто не можете закрыть рассматриваемое окно. ИМХО, есть два решения:

  1. Добавление флага, подобного упомянуту DJNA, или
  2. Требовать, чтобы приобретенная приобретенная на сессию MUTEX, который имеет неудачный побочный эффект сериализации, записывает на сессию.

Какова недостатка в наличии флага Toolate? Другими словами, что пойдет не так, если вы преждевременно удаляете файл? В конце концов, ваша система должна иметь дело с отсутствием файла ...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top