Saya telah menjadwalkan pekerjaan cron untuk dijalankan setiap menit, tetapi kadang-kadang skrip membutuhkan lebih dari satu menit untuk menyelesaikannya dan saya tidak ingin pekerjaan mulai "menumpuk" satu sama lain. Saya kira ini adalah masalah konkurensi - yaitu eksekusi skrip harus saling eksklusif.
Untuk mengatasi masalah tersebut saya membuat skrip mencari keberadaan file tertentu (" lockfile.txt ") dan keluar jika ada atau touch
tidak. Tapi ini semaphore yang cukup buruk! Apakah ada praktik terbaik yang harus saya ketahui? Haruskah saya menulis daemon saja?
sumber
flock -n file command
danflock -n file -c command
?-c
menjalankan perintah yang ditentukan melalui shell (sesuai halaman manual), sedangkan "telanjang" (non--c
) bentuk hanyaexec
s perintah yang diberikan . Meletakkan sesuatu melalui shell memungkinkan Anda untuk melakukan hal-hal seperti shell (seperti menjalankan beberapa perintah yang dipisahkan dengan;
atau&&
), tetapi juga membuka Anda untuk melakukan serangan ekspansi shell jika Anda menggunakan input yang tidak terpercaya.frequent_cron_job
yang mencoba menunjukkan bahwa perintah itu dijalankan setiap menit. Saya telah menghapusnya karena tidak ada yang berguna, dan menyebabkan kebingungan (milik Anda, jika tidak ada orang lain selama ini).Cara terbaik di shell adalah menggunakan flock (1)
sumber
99
dan>
jadi99> /...
Sebenarnya,
flock -n
dapat digunakan sebagai gantilckdo
*, jadi Anda akan menggunakan kode dari pengembang kernel.Berdasarkan contoh womble , Anda akan menulis sesuatu seperti:
BTW, melihat kode, semua
flock
,lockrun
danlckdo
melakukan hal yang sama persis, jadi hanya masalah yang paling mudah tersedia untuk Anda.sumber
Anda dapat menggunakan file kunci. Buat file ini saat skrip dimulai dan hapus ketika skrip selesai. Script, sebelum menjalankan rutinitas utamanya, harus memeriksa apakah file kunci ada dan melanjutkannya.
Lockfiles digunakan oleh skrip init dan oleh banyak aplikasi dan utilitas lain dalam sistem Unix.
sumber
Anda belum menentukan apakah Anda ingin skrip menunggu proses sebelumnya selesai atau tidak. Dengan "Saya tidak ingin pekerjaan mulai" menumpuk "satu sama lain", saya kira Anda menyiratkan bahwa Anda ingin skrip keluar jika sudah berjalan,
Jadi, jika Anda tidak ingin bergantung pada lckdo atau sejenisnya, Anda dapat melakukan ini:
sumber
Ini mungkin juga pertanda bahwa Anda melakukan hal yang salah. Jika pekerjaan Anda berjalan sedekat itu dan sesering itu, mungkin Anda harus mempertimbangkan untuk tidak mengaturnya dan menjadikannya program gaya daemon.
sumber
Daemon cron Anda seharusnya tidak menjalankan pekerjaan jika instance sebelumnya masih berjalan. Saya adalah pengembang dari satu cron daemon dcron , dan kami secara khusus mencoba untuk mencegahnya. Saya tidak tahu bagaimana Vixie cron atau daemon lain menangani ini.
sumber
Saya akan merekomendasikan menggunakan perintah run-one - jauh lebih sederhana daripada berurusan dengan kunci. Dari dokumen:
run-one adalah skrip wrapper yang menjalankan tidak lebih dari satu instance unik dari beberapa perintah dengan serangkaian argumen unik. Ini sering berguna dengan cronjobs, ketika Anda ingin tidak lebih dari satu salinan dijalankan pada satu waktu.
run-this-one persis seperti run-one, kecuali ia akan menggunakan pgrep dan kill untuk menemukan dan membunuh proses yang berjalan yang dimiliki oleh pengguna dan mencocokkan perintah target dan argumen. Perhatikan bahwa run-this-one akan memblokir ketika mencoba untuk mematikan proses pencocokan, sampai semua proses pencocokan mati.
run-one-constant beroperasi persis seperti run-one kecuali bahwa ia respawn "PERINTAH [ARGS]" setiap kali PERINTAH keluar (nol atau non-nol).
keep-one-running adalah alias untuk run-one-constant.
run-one-hingga-success beroperasi persis seperti run-one-constant kecuali ia menjalankan "COMMAND [ARGS]" hingga COMMAND keluar dengan sukses (yaitu, keluar dari nol).
run-satu-hingga-kegagalan beroperasi persis seperti run-satu-terus-menerus kecuali menjalankan "PERINTAH [ARGS]" sampai PERINTAH keluar dengan kegagalan (yaitu, keluar tidak nol).
sumber
Sekarang setelah systemd keluar, ada mekanisme penjadwalan lain pada sistem Linux:
SEBUAH
systemd.timer
Di
/etc/systemd/system/myjob.service
atau~/.config/systemd/user/myjob.service
:Di
/etc/systemd/system/myjob.timer
atau~/.config/systemd/user/myjob.timer
:Jika unit layanan sudah diaktifkan ketika timer berikutnya diaktifkan, maka instance lain dari layanan tidak akan dimulai.
Alternatif, yang memulai pekerjaan sekali saat boot dan satu menit setelah setiap proses selesai:
sumber
Saya telah membuat satu toples untuk menyelesaikan masalah seperti duplikat yang sedang berjalan bisa jadi java atau shell cron. Cukup berikan nama cron di Duplicates.CloseSessions ("Demo.jar") ini akan mencari dan membunuh pid pid yang ada untuk cron ini kecuali yang sekarang. Saya telah menerapkan metode untuk melakukan hal ini. String proname = ManagementFactory.getRuntimeMXBean (). GetName (); String pid = proname.split ("@") [0]; System.out.println ("PID Saat Ini:" + pid);
Dan kemudian bunuh string killid dengan perintah shell lagi
sumber
@ Philip Reynolds menjawab akan mulai mengeksekusi kode setelah 5s menunggu waktu lagi tanpa mendapatkan kunci. Mengikuti Flock sepertinya tidak berfungsi, saya memodifikasi @Philip Reynolds menjawab
sehingga kode tidak akan pernah dieksekusi secara bersamaan. Alih-alih setelah 5 detik menunggu proses akan keluar dengan 1 jika tidak mendapatkan kunci saat itu.
sumber