Quelles commandes Unix peuvent être utilisées en tant que sémaphore / verrou?


34

Je veux exécuter plusieurs scripts shell Bash en parallèle. Cependant, je veux éviter les conditions de course. Quelles commandes Unix sont vraiment atomiques que je pourrais utiliser à cette fin et comment puis-je les utiliser?


Que faites-vous qui nécessite un travail parallèle? Ne pouvez-vous pas exprimer les dépendances de manière à permettre à un parallèle make(1)de prendre le relais? (c.-à-d. make -j 9si vous avez 8 cœurs)? Cela présente l’avantage supplémentaire d’entrelacer les travaux avec une granularité plus fine.
vonbrand

Réponses:


30

Si lockfilen'est pas installé sur votre système, mkdirle travail sera alors effectué: il s'agira d'une opération atomique qui échouera si le répertoire existe déjà (tant que vous n'ajoutez pas le -pcommutateur de ligne de commande).

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

26

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

Cela garantit que le code entre "(" et ")" est exécuté uniquement par un processus à la fois et qu'il attend trop longtemps le verrouillage.


Belle, je ne savais pas à ce sujet. Cependant, il est apparemment spécifique à Linux ...
Riccardo Murri

1
@Riccardo, FreeBSD dispose d' une commande similaire: lockf(1).
Alex B

lockf(1)ne fonctionne pas de la manière utilisée dans cet exemple, cependant. Il ne peut pas prendre un numéro de descripteur de fichier en argument.
Charley

11

lockfile (1) semble être un bon candidat, mais sachez que cela fait partie du paquet procmail , que vous n'avez peut-être pas encore installé sur votre ordinateur. C'est un paquet assez populaire pour qu'il soit packagé pour votre système s'il n'est pas encore installé. Trois des quatre systèmes que j'ai vérifiés l'ont et l'autre le dispose.

Son utilisation est 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

Les options que je vous ai données permettent de réessayer une fois par seconde pendant 15 secondes maximum. Supprimez l'indicateur "-r" si vous souhaitez attendre indéfiniment.


2
Juste pour référence - la page de manuel : linux.die.net/man/1/lockfile . :)
Lucas Jones

Sachez que (selon la page de manuel), "Une fois qu'un fichier est verrouillé, le verrou doit être touché au moins une fois toutes les cinq minutes, sinon le verrou sera considéré comme périmé et les tentatives de verrouillage suivantes aboutiront."
Jay

6

L'appel système mkdir()est atomique sur les systèmes de fichiers POSIX. Donc, en utilisant la mkdircommande de telle sorte qu'elle implique exactement un appel, vous mkdir()atteindriez votre but. (IOW, ne pas utiliser mkdir -p). Le déverrouillage correspondant est rmdirbien sûr.

Caveat emptor: mkdir()pourrait ne pas être atomique sur les systèmes de fichiers du réseau.


est rmdirdonc aussi atomique?
Alexej Magura

3

Peut-être que la commande lockfile fera ce dont vous avez besoin.

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

Cela semble supprimer le mauvais fichier.
Benjamin W.

1

Si vous utilisez uniquement Unix, utilisez fifos. Vous pouvez écrire des enregistrements de travail dans le fifo et faire en sorte que les processus soient lus à partir de ce fichier. Vos lecteurs bloquent alors sur le fifo.

Les fichiers de verrouillage sont ok, mais pour ce que vous décrivez, j'irais avec fifos


1
Pourriez-vous préciser comment, selon vous, les fifres peuvent prévenir les conditions de concurrence?
G-Man dit 'Réintégrez Monica' le

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.