Si lockf
se utiliza con un desplazamiento de 0, ¿cuáles son las diferencias entre flock
y lockf
cuando se usa en modo exclusivo, si lo hay?
Lo pregunto porque estoy leyendo un código que se compila condicionalmente en cualquiera de estas 2 funciones según la plataforma y quiero entender las posibles razones por las que.
La diferencia práctica entre flock()
y lockf()
está en la semántica (comportamiento con respecto al cierre y paso), la aplicabilidad sobre NFS y otros sistemas de archivos compartidos, y si los bloqueos de aviso son visibles para otros procesos que usan fcntl()
cerraduras o no.
La biblioteca que está utilizando simplemente tiene lógica para elegir la semántica deseada en función de la plataforma actual.
Si la semántica (comportamiento sobre el paso del descriptor, bifurcación, etc.) es aceptable, debería preferir lockf()
/fcntl()
se bloquea flock()
se bloquea en Linux, simplemente porque el primero funciona en sistemas de archivos NFS, etc., mientras que el segundo no. (En BSD y Mac OS X, creo que debe usar explícitamente fcntl()
en lugar de.)
En Linux, lockf()
es solo un envoltorio fcntl()
tiempo flock()
los bloqueos están separados (y solo funcionarán en sistemas de archivos locales, no en, por ejemplo, montajes NFS en kernels anteriores a 2.6.12). Es decir, un proceso puede tener una exclusiva de asesoramiento flock()
bloqueo en un archivo, mientras que otro proceso tiene un aviso exclusivo fcntl()
bloqueo en ese mismo archivo. Ambos son bloqueos de aviso, pero no interactúan.
En Mac OS X y FreeBSD, lockf()
/flock()
/fcntl()
todos los bloqueos interactúan, aunque se recomienda a los desarrolladores que utilicen solo una de las interfaces en una aplicación. Sin embargo, solo fcntl()
las cerraduras funcionan Montajes NFS (y, obviamente, solo si tanto el cliente como el servidor NFS se han configurado para admitir bloqueos de registros, lo cual es sorprendentemente raro, por ejemplo, en entornos de alojamiento web; una gran causa de dolores de cabeza para algunos desarrolladores web (framework)).
POSIX no especifica explícitamente cómo lockf()
/flock()
/fcntl()
las cerraduras deben interactuar, y ha habido diferencias en el pasado. Ahora, la situación se ha calmado un poco, y uno puede aproximadamente dilo
-
fcntl()
las cerraduras son las más fiables
En todas las arquitecturas, tienen la mejor oportunidad de funcionar correctamente, por ejemplo, en sistemas de archivos compartidos: montajes NFS y CIFS, por ejemplo.
-
Más amenudo, lockf()
se implementa como “taquigrafía” para fcntl()
La otra alternativa, como “taquigrafía” de flock()
es posible, pero hoy en día es raro.
-
fcntl()
y flock()
tienen diferente semántica wrt. herencia y liberaciones automáticas
fcntl()
las cerraduras se conservan a través de un exec()
pero no heredado a través de un fork()
. Los bloqueos se liberan cuando se cierra el proceso de propiedad. ninguna descriptor que hace referencia al mismo archivo.
En Linux, FreeBSD y MAC OS X, flock()
los bloqueos se acoplan con el descriptor de archivo abierto: pasar el descriptor también pasa el bloqueo. (Las páginas del manual indican que “el bloqueo está en el archivo, no en el descriptor del archivo”. Esto no es una contradiccion. Solo significa que la cerradura se aplica al archivo Todavía está acoplado al descriptor, de tal manera que duplicar el descriptor también pasa el mismo bloqueo). Por lo tanto, es posible que varios procesos tengan el mismo aviso exclusivo. flock()
bloqueo en el mismo archivo al mismo tiempo, si obtuvieron el descriptor del creador después de la flock()
llamada.
El bloqueo de archivos es un problema sorprendentemente complicado. Personalmente, obtuve mejores resultados al simplemente ceñirme a fcntl()
cierre. La semántica wrt. fcntl()
las cerraduras no son las más fáciles de usar y, en ciertos casos, pueden ser francamente exasperantes; es solo que descubrí que produce los mejores resultados, los más confiables, los más portátiles y los menos sorprendentes.
La razón más probable de la compilación condicional es que ninguna de las dos funciones está disponible en todas las plataformas.