Welche Unix-Befehle können als Semaphor / Sperre verwendet werden?
34
Ich möchte mehrere Bash-Shell-Skripte gleichzeitig ausführen. Ich möchte jedoch Rennbedingungen vermeiden. Welche Unix-Befehle sind wirklich atomar, die ich für diesen Zweck verwenden könnte, und wie kann ich sie verwenden?
Was machst du, das erfordert parallele Arbeit? Können Sie die Abhängigkeiten nicht so ausdrücken, dass eine Parallele make(1)übernehmen kann? (also a make -j 9wenn du 8 Kerne hast)? Dies hat den zusätzlichen Vorteil, dass Interleaving-Arbeiten mit einer feineren Granularität ausgeführt werden.
Wenn lockfilees nicht auf Ihrem System installiert ist, mkdirerledigt es die Arbeit: Es ist eine atomare Operation und es schlägt fehl, wenn das Verzeichnis bereits vorhanden ist (solange Sie den -pBefehlszeilenschalter nicht hinzufügen ).
#!/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 10200# Do stuff)200>/var/lock/.myscript.exclusivelock
Dadurch wird sichergestellt, dass der Code zwischen "(" und ")" jeweils nur von einem Prozess ausgeführt wird und der Prozess zu lange auf eine Sperre wartet.
Netter, wusste nichts davon. Es ist jedoch anscheinend Linux-spezifisch ...
Riccardo Murri
1
@Riccardo hat FreeBSD einen ähnlichen Befehl: lockf(1).
Alex B
lockf(1)funktioniert jedoch nicht so wie in diesem Beispiel. Eine Dateideskriptornummer kann nicht als Argument verwendet werden.
Charley
11
lockfile (1) sieht aus wie ein guter Kandidat, obwohl es Teil des procmail- Pakets ist, das Sie möglicherweise noch nicht auf Ihrem Computer installiert haben. Es ist ein beliebtes Paket, das für Ihr System gepackt werden sollte, wenn es noch nicht installiert ist. Drei der vier von mir überprüften Systeme haben es und das andere hat es zur Verfügung.
Die Benutzung ist einfach:
#!/bin/sh
LOCKFILE=$HOME/.myscript/lock
mkdir -p `dirname $LOCKFILE`
echo Waitingfor 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 1fi
Die Optionen, die ich angegeben habe, lassen es bis zu 15 Sekunden lang einmal pro Sekunde wiederholen. Löschen Sie das Flag "-r", wenn Sie möchten, dass es für immer wartet.
Beachten Sie, dass (laut Manpage) "Sobald eine Datei gesperrt ist, muss die Sperre mindestens alle fünf Minuten berührt werden, da sonst die Sperre als veraltet angesehen wird und nachfolgende Sperrversuche erfolgreich sind."
Jay
6
Der Systemaufruf mkdir()ist bei POSIX-Dateisystemen atomar. Verwenden Sie den mkdirBefehl also so, dass genau ein Aufruf mkdir()erforderlich ist, um Ihren Zweck zu erreichen. (IOW, nicht benutzen mkdir -p). Das entsprechende Entsperren ist rmdirnatürlich.
Vorsichtsmaßnahme: mkdir()Möglicherweise sind Netzwerk-Dateisysteme nicht atomar.
Wenn Sie nur unter Unix arbeiten, verwenden Sie fifos. Sie können Arbeitsdatensätze in das Fifo schreiben und Prozesse aus dieser Datei lesen lassen, und Ihre Leser blockieren die Fifos.
Sperrdateien sind in Ordnung, aber für das, was Sie beschreiben, würde ich mit Fifos gehen
make(1)
übernehmen kann? (also amake -j 9
wenn du 8 Kerne hast)? Dies hat den zusätzlichen Vorteil, dass Interleaving-Arbeiten mit einer feineren Granularität ausgeführt werden.Antworten:
Wenn
lockfile
es nicht auf Ihrem System installiert ist,mkdir
erledigt es die Arbeit: Es ist eine atomare Operation und es schlägt fehl, wenn das Verzeichnis bereits vorhanden ist (solange Sie den-p
Befehlszeilenschalter nicht hinzufügen ).quelle
flock(1)
Dadurch wird sichergestellt, dass der Code zwischen "(" und ")" jeweils nur von einem Prozess ausgeführt wird und der Prozess zu lange auf eine Sperre wartet.
quelle
lockf(1)
.lockf(1)
funktioniert jedoch nicht so wie in diesem Beispiel. Eine Dateideskriptornummer kann nicht als Argument verwendet werden.lockfile (1) sieht aus wie ein guter Kandidat, obwohl es Teil des procmail- Pakets ist, das Sie möglicherweise noch nicht auf Ihrem Computer installiert haben. Es ist ein beliebtes Paket, das für Ihr System gepackt werden sollte, wenn es noch nicht installiert ist. Drei der vier von mir überprüften Systeme haben es und das andere hat es zur Verfügung.
Die Benutzung ist einfach:
Die Optionen, die ich angegeben habe, lassen es bis zu 15 Sekunden lang einmal pro Sekunde wiederholen. Löschen Sie das Flag "-r", wenn Sie möchten, dass es für immer wartet.
quelle
Der Systemaufruf
mkdir()
ist bei POSIX-Dateisystemen atomar. Verwenden Sie denmkdir
Befehl also so, dass genau ein Aufrufmkdir()
erforderlich ist, um Ihren Zweck zu erreichen. (IOW, nicht benutzenmkdir -p
). Das entsprechende Entsperren istrmdir
natürlich.Vorsichtsmaßnahme:
mkdir()
Möglicherweise sind Netzwerk-Dateisysteme nicht atomar.quelle
rmdir
also auch atom?Vielleicht wird der Befehl lockfile das tun, was Sie brauchen.
quelle
Wenn Sie nur unter Unix arbeiten, verwenden Sie fifos. Sie können Arbeitsdatensätze in das Fifo schreiben und Prozesse aus dieser Datei lesen lassen, und Ihre Leser blockieren die Fifos.
Sperrdateien sind in Ordnung, aber für das, was Sie beschreiben, würde ich mit Fifos gehen
quelle
Wie hier beschrieben: " Korrektes Sperren in Shell-Skripten? " Mit dem FLOM-Tool (Free LOck Manager) wird das Serialisieren von Befehlen und Shell-Skripten so einfach wie das Ausführen
Mit FLOM können Sie komplexere Anwendungsfälle (verteiltes Sperren, Lese- / Schreibvorgänge, numerische Ressourcen usw.) implementieren, wie hier erläutert: http://sourceforge.net/p/flom/wiki/FLOM%20by%20examples/
quelle