Paralel olarak birden fazla Bash kabuk betiği çalıştırmak istiyorum. Ancak yarış koşullarından kaçınmak istiyorum. Hangi Unix komutları bu amaçla kullanabileceğim gerçekten atomiktir ve bunları nasıl kullanabilirim?
Paralel olarak birden fazla Bash kabuk betiği çalıştırmak istiyorum. Ancak yarış koşullarından kaçınmak istiyorum. Hangi Unix komutları bu amaçla kullanabileceğim gerçekten atomiktir ve bunları nasıl kullanabilirim?
Yanıtlar:
Eğer lockfile
sisteminizde yüklü değilse, o zaman mkdir
bunun bir atom işlemdir ve dizin zaten (sürece katmayan olarak var eğer başarısız: iş yapacak -p
komut satırı anahtarı).
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"
}
#!/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
Bu, "(" ve ")" arasındaki kodun aynı anda yalnızca bir işlem tarafından çalıştırılmasını ve işlemin çok uzun süre kilitlenmesini beklemesini sağlar.
lockf(1)
.
lockf(1)
Yine de, bu örnekte kullanılan şekilde çalışmaz. Bir dosya tanıtıcı numarasını argüman olarak kabul edemez.
lockfile (1) , makinenize henüz yüklememiş olabileceğiniz procmail paketinin bir parçası olmasına rağmen, iyi bir aday gibi görünüyor . Henüz kurulmamışsa, sisteminiz için paketlenmesi gereken yeterince popüler bir pakettir. Kontrol ettiğim dört sistemden üçünde buna, diğerinde mevcut.
Kullanımı basittir:
#!/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
Verdiğim seçenekler saniyede bir kez 15 saniyeye kadar tekrar denemesini sağlar. Sonsuza dek beklemesini istiyorsanız, "-r" bayrağını bırakın.
Sistem çağrısı mkdir()
POSIX dosya sistemlerinde atomiktir. Bu nedenle, mkdir
komutu mkdir()
, amacınıza ulaşmak için tek bir çağrıyı içerecek şekilde kullanmak. (IOW, kullanmayın mkdir -p
). Karşılık gelen kilit açma rmdir
elbette.
Uyarıcı emptor: mkdir()
ağ dosya sistemlerinde atomik olmayabilir.
rmdir
nedenle de atomik mi?
Belki de lockfile komutu ihtiyacınız olanı yapar.
lockfile ~/.config/mylockfile.lock
.....
rm -f important.lock
Sadece Unix ile çalışıyorsanız, fifos kullanın. Çalışma kayıtlarını fifoya yazabilir ve bu dosyadan işlemlerin okunmasını sağlayabilirsiniz; okuyucularınız beşlikte engelleyecektir.
Kilit dosyaları iyi, ancak tanımladığınız şey için fifos ile giderim
Burada belirtildiği gibi: " Kabuk komut dosyalarında doğru kilitleme mi? ", FLOM (Free LOck Manager) aracını kullanarak, komutları ve kabuk komut dosyalarının serileştirilmesi
flom -- command_to_serialize
FLOM, burada açıklanan şekilde daha sofistike kullanım durumları (dağıtılmış kilitleme, okuyucular / yazıcılar, sayısal kaynaklar, vb.) Uygulamanıza olanak sağlar: http://sourceforge.net/p/flom/wiki/FLOM%20by%20examples/
make(1)
ele geçirilmesine izin verecek şekilde ifade edemez misiniz ? (yani,make -j 9
8 çekirdeğiniz varsa bir yapalım )? Bu, daha ince ayrıntı dereceli birleştirme çalışmasının ilave avantajına sahiptir.