Domanda

Si prega di notare che questo non è duplicato di r File / w bloccaggio e scollegare . . (La differenza -. Operazioni piattaforma di file come il blocco e la cancellazione hanno totalmente diverse semantiche, così il sultion sarebbe diverso)

Ho seguente problema. Voglio creare un deposito di sessione basata su file system in cui ogni sessione di dati sono memorizzati in un semplice file chiamato con ID di sessione.

Voglio seguente API: write(sid,data,timeout), read(sid,data,timeout), remove(sid) dove SID == nome del file, anche io voglio avere un qualche tipo di GC che possono rimuovere tutte le sessioni scaduta a.

Molto semplice compito se si lavora con unico processo, ma assolutamente non banale quando si lavora con più processi o anche su cartelle condivise.

La soluzione più semplice ho pensato è stata:

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)

Ma AFIAK non posso chiamare DeleteFile sul file bloccato opended (a differenza di Unix in cui il blocco dei file è non è permesso obbligatorio e unlink per i file aperti.

Ma se metto DeleteFile al di fuori del blocco ciclo cattivo scenario potrebbe accadere

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

Qualcuno ha un'idea di come tale problema può essere risolto? Ci sono dei trucchi che permettono coniugare il blocco dei file e file di rimozione o di rendere il funzionamento in archivio atomica (Win32)?

Note:

  • Non voglio usare Database,
  • cerco una soluzione per Win32 API per NT 5.01 e sopra

Grazie.

È stato utile?

Soluzione

Io non capisco come questo dovrebbe funzionare. Tuttavia, l'eliminazione di un file che viene aperto da un altro processo è possibile. Il processo che crea il file deve utilizzare il flag FILE_SHARE_DELETE per l'argomento dwShareMode di CreateFile (). Una chiamata successiva DeleteFile () avrà successo. Il file in realtà non vengono rimossi dal file system fino a quando l'ultima maniglia su di esso è chiuso.

Altri suggerimenti

Al momento è i dati nel record che consente al GC per determinare se il record è scaduta. Che ne dite di estendere tale informazioni di pulizia con una bandiera "TooLateWeAlreadyTimedItOut".

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

In altre parole stiamo usando un tipo di approccio blocco ottimistico. Questo richiede una certa complessità supplementare nel Writer, ma ora non sei dipendente da qualsiasi rughe OS-specifc.

Non ho chiaro che cosa accade nel caso:

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

Qualunque cosa avete in programma per questo caso può essere utilizzato anche nel caso "TooLate"

A cura di aggiungere:

Hai detto che è valido per questa sequenza si verifichi:

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

Lo scrittore può trattare flag "TooLate" come identico a questo caso. Si crea solo un nuovo file , con un nome diverso, utilizzare un numero di versione come parte finale del suo nome. L'apertura di un file di sessione per la prima volta richiede una ricerca di directory, ma allora si può riporre l'ultimo nome nella sessione.

Questa si assume che non ci può essere un solo thread di scrittura per una determinata sessione, o che siamo in grado di mediare tra due thread Writer creazione del file, ma che deve essere vero per il vostro semplice caso GC / Writer per lavorare.

Per Windows, è possibile utilizzare il FILE_FLAG_DELETE_ON_CLOSE opzione per CreateFile - che farà sì che il file da eliminare quando si chiude la maniglia. Ma io non sono sicuro che questo soddisfi le vostre semantica (perché non credo che si possa cancellare l'attributo di eliminazione-on-vicino.

Ecco un altro pensiero. Che dire di rinominare il file prima di eliminarlo? Semplicemente non si può chiudere la finestra in cui arriva la scrittura nel dopo aver deciso di eliminare il file, ma cosa succede se si rinomina il file prima di cancellarlo? Poi, quando arriva il write in essa vedrete che il file di sessione non esiste e ricrearlo.

La cosa fondamentale da tenere a mente è che semplicemente non è possibile chiudere la finestra in questione. IMHO ci sono due soluzioni:

  1. L'aggiunta di una bandiera come djna menzionato o
  2. richiedono che una per ogni sessione di nome mutex essere acquisita che ha l'effetto collaterale di serializzazione scrive sulla sessione.

Qual è il lato negativo di avere una bandiera TooLate? In altre parole, ciò che va male se si elimina il file prematuramente? Dopo tutto il sistema deve fare i conti con il file non sia presente ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top