¿Qué comandos de Unix se pueden utilizar como semáforo/bloqueo?

¿Qué comandos de Unix se pueden utilizar como semáforo/bloqueo?

Quiero ejecutar varios scripts de shell Bash en paralelo. Sin embargo, quiero evitar las condiciones de carrera. ¿Qué son los comandos de Unix?realmenteatómicos que podría usar para este propósito, y ¿cómo puedo usarlos?

Respuesta1

flock(1)

#!/bin/bash

# Makes sure we exit if flock fails.
set -e

(
  # Wait for lock on /var/lock/.myscript.exclusivelock (fd 200) for 10 seconds
  flock -x -w 10 200

  # Do stuff

) 200>/var/lock/.myscript.exclusivelock

Esto garantiza que el código entre "(" y ")" se ejecute solo por un proceso a la vez y que el proceso espere demasiado tiempo a que se bloquee.

Respuesta2

Si lockfileno está instalado en su sistema, entonces mkdirhará el trabajo: es una operación atómica y falla si el directorio ya existe (siempre que no agregue el -pmodificador de línea de comandos).

create_lock_or_wait () {
  path="$1"
  wait_time="${2:-10}"
  while true; do
        if mkdir "${path}.lock.d"; then
           break;
        fi
        sleep $wait_time
  done
}

remove_lock () {
  path="$1"
  rmdir "${path}.lock.d"
}

Respuesta3

lockfile(1) parece un buen candidato, aunque tenga en cuenta que es parte delcorreo electrónicopaquete, que es posible que aún no haya instalado en su máquina. Es un paquete lo suficientemente popular como para incluirlo en su sistema si aún no está instalado. Tres de los cuatro sistemas que revisé lo tienen y el otro lo tiene disponible.

Usarlo es simple:

#!/bin/sh
LOCKFILE=$HOME/.myscript/lock
mkdir -p `dirname $LOCKFILE`

echo Waiting for lock $LOCKFILE...
if lockfile -1 -r15 $LOCKFILE
then
    # Do protected stuff here
    echo Doing protected stuff...

    # Then, afterward, clean up so another instance of this script can run
    rm -f $LOCKFILE
else
    echo "Failed to acquire lock!  lockfile(1) returned $?"
    exit 1
fi

Las opciones que le he dado hacen que se reintente una vez por segundo durante hasta 15 segundos. Suelta el indicador "-r" si quieres que espere para siempre.

Respuesta4

Quizás el comando lockfile haga lo que necesita.

lockfile ~/.config/mylockfile.lock
.....
rm -f important.lock

información relacionada