ejemplos - pthread mutex lock
flock vs lockf en Linux (2)
Si se usa lockf
con un desplazamiento de 0, ¿cuáles son las diferencias entre flock
y lockf
cuando se usa en modo exclusivo, si existe?
Lo pregunto porque estoy leyendo el código que compila condicionalmente en cualquiera de estas 2 funciones basadas en la plataforma y quiero entender las posibles razones de por qué.
La diferencia práctica entre flock()
y lockf()
encuentra en la semántica (comportamiento con respecto al cierre y paso), aplicabilidad sobre NFS y otros sistemas de archivos compartidos, y si los bloqueos de aviso son visibles para otros procesos utilizando fcntl()
o no .
La biblioteca que está utilizando simplemente tiene lógica para elegir la semántica deseada según la plataforma actual.
Si la semántica (comportamiento sobre el paso de descriptores, forking, etc.) es aceptable, debería preferir lockf()
/ fcntl()
bloquea sobre flock()
en Linux, simplemente porque la primera funciona en sistemas de archivos NFS, etc., mientras que la segunda no. (En BSDs y Mac OS X, creo que necesitas usar explícitamente fcntl()
, en su lugar).
En Linux, lockf()
es solo un envoltorio alrededor de fcntl()
, mientras que los bloqueos flock()
son independientes (y solo funcionarán en sistemas de archivos locales, no en montajes NFS en kernels anteriores a 2.6.12). Es decir, un proceso puede tener un bloqueo exclusivo de aviso flock()
en un archivo, mientras que otro proceso tiene un fcntl()
exclusivo de aviso fcntl()
en ese mismo archivo. Ambos son bloqueos de asesoría, pero no interactúan.
En Mac OS X y FreeBSD , los lockf()
/ flock()
/ fcntl()
interactúan, aunque se recomienda a los desarrolladores usar solo una de las interfaces en una aplicación. Sin embargo, solo los fcntl()
funcionan en montajes NFS (y, obviamente, solo si tanto el cliente como el servidor NFS se han configurado para admitir bloqueos de registros, lo que es sorprendentemente raro en entornos de alojamiento web, por ejemplo, una causa enorme de problemas para algunas web framework) desarrolladores).
POSIX no especifica explícitamente cómo deben interactuar los bloqueos lockf()
/ flock()
/ fcntl()
, y ha habido diferencias en el pasado. Ahora, la situación se ha calmado un poco, y se puede decir aproximadamente que
fcntl()
bloqueosfcntl()
son los más confiables.En todas las arquitecturas, tienen la mejor oportunidad de trabajar directamente en, por ejemplo, sistemas de archivos compartidos: montajes NFS y CIFS, por ejemplo.
La mayoría de las veces,
lockf()
se implementa como "taquigrafía" parafcntl()
La otra alternativa, como "taquigrafía" para
flock()
, es posible, pero hoy en día es poco frecuente.fcntl()
yflock()
tienen diferentes semánticas wrt. Herencia y liberaciones automáticas.fcntl()
bloqueosfcntl()
se conservan en unexec()
, pero no se heredan en unfork()
. Los bloqueos se liberan cuando el proceso de propiedad cierra cualquier descriptor que haga referencia al mismo archivo.En Linux, FreeBSD y MAc OS X, los bloqueos de
flock()
se juntan con el descriptor de archivo abierto: pasar el descriptor también pasa el bloqueo. (Las páginas de manual indican que "el bloqueo está en el archivo, no en el descriptor del archivo" . Esto no es una contradicción. Simplemente significa que el bloqueo se aplica al archivo. Todavía está acoplado al descriptor, de tal manera esa duplicación del descriptor también pasa el mismo bloqueo, también.) Por lo tanto, es posible que múltiples procesos tengan el mismo bloqueo exclusivo deflock()
en el mismo archivo al mismo tiempo, si obtuvieron el descriptor del originador después delflock()
llamar.
El bloqueo de archivos es un tema sorprendentemente complicado. Personalmente, he obtenido mejores resultados simplemente apegándome al bloqueo fcntl()
. La semántica wrt. fcntl()
bloqueos fcntl()
no son los más fáciles de trabajar, y en ciertos casos pueden ser francamente molestos; es solo que lo he encontrado para obtener los mejores resultados: más fiables, más portátiles y menos sorprendentes.
La razón más probable para la compilación condicional es que ninguna de las dos funciones está disponible en todas las plataformas.