2008-11-28 21 views
9

este es el enfoque estándar para crear bloqueos utilizando el sistema de archivos. Por ejemplo, visudo lo utiliza:condición de carrera en el bloqueo común en el archivo?

[ -f ".lock" ] && exit 1 
touch .lock 
# do something 
rm .lock 

1) Estoy confundido, porque no es una condición de carrera, sin embargo, que Linux utiliza

2) hay una mejor manera de bloquear en los archivos de la concha?

3) o tengo que usar directorios en su lugar?

Solución encontrada: man lockfile.

+1

Las preguntas deben marcarse como "[resuelto]" seleccionando una respuesta, no editando el título y agregando "[resuelto]". –

+0

problema es que no puedo marcar mi propia respuesta como "aceptado" –

+2

No creo que su respuesta sea la mejor, francamente :) –

Respuesta

17

Sí, de hecho hay una condición de carrera en el script de muestra. Puede usar la opción nocler de bash para obtener una falla en caso de una carrera, cuando un guión diferente se cuela entre la prueba y el toque.

Se describe here. He extracté la pieza fundamental, con un par de anotaciones (con el prefijo BK :):

Una posible solución a esto es utilizar redirección de IO y el modo noclobber de fiesta, que no volverá a dirigir a un archivo existente . Podemos usar algo similar a:

if (set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null; 
then 
    # BK: this will cause the lock file to be deleted in case of other exit 
    trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT 

    # critical-section BK: (the protected bit) 

    rm -f "$lockfile" 
    trap - INT TERM EXIT 
else 
    echo "Failed to acquire lockfile: $lockfile." 
    echo "Held by $(cat $lockfile)" 
fi 
+0

noclobber es útil, gracias –

+1

¡Gracias! [Repostado aquí] (http://stackoverflow.com/a/31955862/471376). – JamesThomasMoon1979

0

parece que he encontrado una solución más fácil: el hombre fichero de bloqueo

+1

Tenga en cuenta que el archivo de bloqueo no es portátil, es posible que no esté disponible; es parte de procmail (AFAIK). –

+0

shell de Linux, incluso menos :) –

+0

El shell es más portátil que procmail, en la medida en que es más probable que tenga bash que procmail. Tengo bash en Solaris, Linux, Mac y Windows aquí. 'lockfile' no está en ninguno de ellos. –

8

Trate de comandos rebaño:

exec 200>"$LOCK_FILE" 
flock -e -n 200 || exit 1 

saldrá si el archivo de bloqueo está bloqueado. Es atómico y funcionará con la versión más reciente de NFS.

Hice una prueba. He creado un archivo de contador con 0 en ella y ejecuta la siguiente en un bucle en dos servidores de forma simultánea: 500 veces

#!/bin/bash 

exec 200>/nfs/mount/testlock 
flock -e 200 

NO=`cat /nfs/mount/counter` 
echo "$NO" 
let NO=NO+1 
echo "$NO" > /nfs/mount/counter 

Un nodo estaba luchando con el otro para el bloqueo. Cuando las dos ejecuciones finalizaron, el contenido del archivo fue de 1000. Lo intenté varias veces y siempre funciona.

Nota: El cliente NFS es RHEL 5.2 y el servidor utilizado es NetApp.

+0

¡excelente publicación! gracias – Janning

+0

Razonablemente buena cobertura en flock: en mi muestreo, lo tengo en Cygwin y Linux, pero no en Solaris o Mac. –

+1

¿Te importaría explicar la sintaxis un poco más? Me pregunto especialmente sobre 'exec 200>" $ LOCK_FILE "'. Voy a resolver esto con las páginas man, pero tu respuesta sería mucho mejor si explicara lo que hacen estas líneas. –

Cuestiones relacionadas