Pregunta

Tenga en cuenta que esto no es duplicado de Archivo r / w bloqueo y desvincular . . (La diferencia -. Plataforma de operaciones de archivos como el bloqueo y eliminación tiene totalmente diferentes semántica, así el sultion sería diferente)

He siguiente problema. Quiero crear un almacenamiento de sesión basada en sistema de archivos donde los datos de cada sesión se almacena en archivos simple llamada con ID de sesión.

Quiero siguientes API: write(sid,data,timeout), read(sid,data,timeout), remove(sid) donde sid == nombre de archivo, también quiero tener algún tipo de GC que pueden eliminar todas las sesiones de tiempo de espera superado.

tarea relativamente fácil de si se trabaja con un solo proceso, pero absolutamente no es trivial cuando se trabaja con múltiples procesos o incluso por encima de las carpetas compartidas.

La solución más simple pensé fue:

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)

Pero AFIAK No puedo llamar DeleteFile el archivo bloqueado opended (al contrario que en Unix, donde el bloqueo de archivos es No se permite obligatorios y de desenlace para los archivos abiertos.

Pero si pongo DeleteFile fuera del bucle de bloqueo de mal escenario que puede suceder

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

¿Alguien tiene una idea de cómo tal problema puede ser resuelto? ¿Hay trucos que permiten combinar el bloqueo de archivos y presentar remoción o hacer la operación en el archivo atómica (Win32)?

Notas:

  • No quiero usar la base de datos,
  • busco una solución para la API de Win32 para NT 5.01 y superior

Gracias.

¿Fue útil?

Solución

No entiendo muy bien cómo se supone que funciona. Sin embargo, la eliminación de un archivo que está abierto por otro proceso es posible. El proceso que crea el archivo tiene que usar la bandera FILE_SHARE_DELETE para el argumento dwShareMode de CreateFile (). Un DeleteFile () llamada posterior tendrá éxito. El archivo en realidad no se eliminan del sistema de archivos hasta el último manija en ella se cierra.

Otros consejos

Actualmente tienes datos en el registro que permite que el GC para determinar si el registro se mide el tiempo hacia fuera. ¿Qué hay de extender esa información limpieza con una bandera "TooLateWeAlreadyTimedItOut".

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

En otras palabras, estamos utilizando una especie de enfoque de bloqueo optimista. Esto requiere algo de complejidad adicional en el escritor, pero ahora usted no es dependiente de las arrugas OS-specifc.

No me queda claro lo que sucede en el caso:

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

Lo que usted ha planeado para este caso también se puede utilizar en el caso "Toolate"

Editado para añadir:

Usted ha dicho que es válida para que ocurra esta secuencia:

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

El escritor puede tratar la bandera "Toolate" como idéntica a este caso. Simplemente crea un nuevo archivo , con un nombre diferente, utilice un número de versión como parte posterior de su nombre. La apertura de un archivo de sesión por primera vez requiere una búsqueda de directorio, pero entonces se puede esconder el último nombre en la sesión.

Esto no asuma que sólo puede haber un hilo escritor para una sesión dada, o que puede mediar entre dos hilos del escritor de crear el archivo, pero que debe ser cierto para el caso simple GC / escritor para trabajar.

Para Windows, puede utilizar el FILE_FLAG_DELETE_ON_CLOSE opción de CreateFile - que hará que el archivo que se elimina al cerrar el mango. Pero no estoy seguro de que esto satisface sus semántica (porque no creo que se pueda borrar el atributo de eliminación al cerrar.

Aquí hay otro pensamiento. ¿Qué hay de cambiar el nombre del archivo antes de eliminarlo? Simplemente no se puede cerrar la ventana en la escritura viene después de que decidió eliminar el archivo, pero lo que si cambia el nombre del archivo antes de eliminarlo? Luego, cuando la escritura viene en ella verá que el archivo de sesión no existe y volver a crearlo.

La clave para tener en cuenta es que simplemente no se puede cerrar la ventana en cuestión. En mi humilde opinión hay dos soluciones:

  1. Adición de una bandera como djna mencionado o
  2. Exigir que un mutex llamado por sesión será adquirida que tiene el efecto secundario desafortunado de la serialización de las escrituras de la sesión.

¿Cuál es la desventaja de tener una bandera Toolate? En otras palabras, lo que va mal si se elimina el archivo antes de tiempo? Después de todo su sistema tiene que lidiar con no estar presente en el archivo ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top