Saya ingin menjalankan beberapa skrip Bash shell secara paralel. Namun, saya ingin menghindari kondisi balapan. Apa perintah Unix yang benar - benar atom yang bisa saya gunakan untuk tujuan ini, dan bagaimana saya bisa menggunakannya?
Saya ingin menjalankan beberapa skrip Bash shell secara paralel. Namun, saya ingin menghindari kondisi balapan. Apa perintah Unix yang benar - benar atom yang bisa saya gunakan untuk tujuan ini, dan bagaimana saya bisa menggunakannya?
Jawaban:
Jika lockfile
tidak diinstal pada sistem Anda, maka mkdir
akan melakukan pekerjaan: ini adalah operasi atom, dan gagal jika direktori sudah ada (selama Anda tidak menambahkan -p
saklar baris perintah).
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
Ini memastikan bahwa kode antara "(" dan ")" dijalankan hanya oleh satu proses pada satu waktu dan bahwa proses menunggu kunci terlalu lama.
lockf(1)
.
lockf(1)
tidak bekerja dengan cara yang digunakan dalam contoh ini. Tidak dapat menggunakan nomor deskriptor file sebagai argumen.
lockfile (1) terlihat seperti kandidat yang baik, namun berhati-hatilah bahwa itu adalah bagian dari paket procmail , yang mungkin belum Anda instal pada mesin Anda. Ini adalah paket yang cukup populer sehingga harus dikemas untuk sistem Anda jika belum diinstal. Tiga dari empat sistem yang saya periksa memilikinya, dan yang lainnya memilikinya.
Penggunaannya sederhana:
#!/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
Opsi yang saya berikan membuatnya coba lagi satu detik selama 15 detik. Jatuhkan bendera "-r" jika Anda ingin menunggu selamanya.
Panggilan sistem mkdir()
bersifat atom pada sistem file POSIX. Jadi, menggunakan mkdir
perintah sedemikian rupa sehingga hanya melibatkan satu panggilan untuk mkdir()
mencapai tujuan Anda. (TKI, jangan gunakan mkdir -p
). Buka kunci yang sesuai rmdir
tentu saja.
Caveat emptor: mkdir()
mungkin bukan atom pada sistem file jaringan.
rmdir
karena itu juga atom?
Mungkin perintah lockfile akan melakukan apa yang Anda butuhkan.
lockfile ~/.config/mylockfile.lock
.....
rm -f important.lock
Jika Anda hanya menjalankan Unix, gunakan fifos. Anda dapat menulis catatan kerja ke fifo dan meminta proses membaca dari file ini dan pembaca Anda akan memblokir fifos.
File kunci tidak masalah, tetapi untuk apa yang Anda jelaskan saya akan menggunakan fifos
Seperti yang diposting di sini: " Mengunci yang benar dalam skrip shell? ", Menggunakan alat FLOM (Free LOck Manager) , membuat serialisasi perintah dan skrip shell menjadi semudah menjalankan
flom -- command_to_serialize
FLOM memungkinkan Anda untuk menerapkan kasus penggunaan yang lebih lunak (penguncian terdistribusi, pembaca / penulis, sumber daya numerik, dll ...) seperti yang dijelaskan di sini: http://sourceforge.net/p/flom/wiki/FLOM%20by%20examples/
make(1)
untuk mengambil alih? (Yaitu, lakukanmake -j 9
jika Anda memiliki 8 core)? Ini memiliki keuntungan tambahan dari pekerjaan interleaving dengan granularity yang lebih halus.