Quais comandos Unix podem ser usados ​​como semáforo/bloqueio?

Quais comandos Unix podem ser usados ​​como semáforo/bloqueio?

Quero executar vários scripts de shell Bash em paralelo. No entanto, quero evitar condições de corrida. O que são comandos Unixverdadeiramenteatômicos que eu poderia usar para esse fim, e como posso usá-los?

Responder1

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

Isso garante que o código entre "(" e ")" seja executado apenas por um processo por vez e que o processo espere muito tempo por um bloqueio.

Responder2

Se lockfilenão estiver instalado no seu sistema, então mkdirfará o trabalho: é uma operação atômica e falhará se o diretório já existir (desde que você não adicione a -popção de linha de comando).

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"
}

Responder3

lockfile(1) parece um bom candidato, mas esteja ciente de que faz parte doprocmailpacote, que talvez você ainda não tenha instalado em sua máquina. É um pacote popular o suficiente para ser empacotado para o seu sistema, caso ainda não esteja instalado. Três dos quatro sistemas que verifiquei possuem e o outro está disponível.

Usá-lo é simples:

#!/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

As opções que forneci fazem com que ele tente novamente uma vez por segundo por até 15 segundos. Solte o sinalizador "-r" se quiser esperar para sempre.

Responder4

Talvez o comando lockfile faça o que você precisa.

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

informação relacionada