linux - race - condicion de carrera java ejemplo
condición de carrera en el bloqueo común en el archivo? (4)
este es el enfoque estándar para crear bloqueos utilizando el sistema de archivos. Por ejemplo, visudo lo usa:
[ -f ".lock" ] && exit 1
touch .lock
# do something
rm .lock
1) Estoy confundido, porque hay una condición de carrera, pero Linux lo usa
2) ¿hay una mejor manera de bloquear archivos desde el shell?
3) o tengo que usar directorios en su lugar?
Solución encontrada: man lockfile.
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 aquí . Extraje la parte crítica, con un par de anotaciones (prefijadas por BK :):
Una posible solución a esto es usar la redirección IO y el modo noclobber de bash, que no redireccionará 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
parece que encontré una solución más fácil: hombre lockfile
Pruebe el comando flock:
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. Creé un archivo de contador con 0 y ejecuté lo siguiente en un bucle en dos servidores simultáneamente 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 peleando con el otro por la cerradura. 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.