Saya memiliki skrip baris perintah yang melakukan panggilan API dan memperbarui database dengan hasilnya.
Saya memiliki batas 5 panggilan API per detik dengan penyedia API. Script membutuhkan waktu lebih dari 0,2 detik untuk dieksekusi.
- Jika saya menjalankan perintah secara berurutan, itu tidak akan berjalan cukup cepat dan saya hanya akan membuat 1 atau 2 panggilan API per detik.
- Jika saya menjalankan perintah secara berurutan, tetapi secara bersamaan dari beberapa terminal, saya mungkin melebihi batas 5 panggilan / detik.
Jika ada cara untuk mengatur utas sehingga skrip baris perintah saya dijalankan hampir tepat 5 kali per detik?
Misalnya sesuatu yang akan berjalan dengan 5 atau 10 utas, dan tidak ada utas yang akan menjalankan skrip jika utas sebelumnya telah mengeksekusinya kurang dari 200 ms yang lalu.
command-line
multithreading
Benjamin
sumber
sumber
Jawaban:
Pada sistem GNU dan jika sudah
pv
, Anda dapat melakukannya:The
-P20
adalah untuk mengeksekusi paling 20$cmd
pada waktu yang sama.-L10
membatasi laju hingga 10 byte per detik, jadi 5 baris per detik.Jika Anda
$cmd
menjadi dua lambat dan menyebabkan batas 20 tercapai, makaxargs
akan berhenti membaca sampai satu$cmd
contoh setidaknya kembali.pv
masih akan terus menulis ke pipa pada kecepatan yang sama, sampai pipa menjadi penuh (yang pada Linux dengan ukuran pipa default 64KiB akan memakan waktu hampir 2 jam).Pada saat itu,
pv
akan berhenti menulis. Tetapi meskipun demikian, ketikaxargs
resume membaca,pv
akan mencoba dan mengejar dan mengirim semua baris yang seharusnya telah dikirim sebelumnya secepat mungkin sehingga mempertahankan rata-rata 5 baris per detik secara keseluruhan.Apa itu artinya bahwa selama mungkin dengan 20 proses untuk memenuhi 5 run per detik pada persyaratan rata-rata, itu akan melakukannya. Namun ketika batas tercapai, laju di mana proses baru dimulai tidak akan didorong oleh timer pv tetapi oleh tingkat di mana contoh cmd sebelumnya kembali. Misalnya, jika 20 saat ini sedang berjalan dan telah selama 10 detik, dan 10 dari mereka memutuskan untuk menyelesaikan semuanya pada saat yang sama, maka 10 yang baru akan dimulai sekaligus.
Contoh:
Rata-rata, itu akan menjadi 5 kali per detik bahkan jika penundaan antara dua berjalan tidak selalu tepat 0,2 detik.
Dengan
ksh93
(atau denganzsh
jikasleep
perintah Anda mendukung pecahan detik):Itu tidak membatasi jumlah konkuren
your-command
.sumber
pv
perintahnya sepertinya persis seperti yang saya cari, tidak bisa berharap lebih baik! Hanya di baris ini:,yes | pv -qL10 | xargs -n1 -P20 sh -c "$cmd" sh
bukankah itush
berlebihan?sh
adalah untuk skrip$0
Anda$cmd
. Ini juga digunakan dalam pesan kesalahan oleh shell. Tanpa itu,$0
akany
dariyes
, jadi Anda akan mendapatkan pesan kesalahan sepertiy: cannot execute cmd
... Anda juga bisa melakukannyayes sh | pv -qL15 | xargs -n1 -P20 sh -c "$cmd"
sh
; dan dalam pengujian saya, ketika saya menghapusnya, saya tidak dapat melihat perbedaan!$cmd
memang menggunakan$0
(mengapa?) Dan untuk pesan kesalahan. Coba misalnya dengancmd=/
; tanpa yang keduash
, Anda akan melihat sesuatu sepertiy: 1: y: /: Permission denied
bukannyash: 1: sh: /: Permission denied
Secara sederhana, jika perintah Anda bertahan kurang dari 1 detik, Anda bisa memulai 5 perintah setiap detik. Jelas, ini sangat meledak.
Jika perintah Anda mungkin membutuhkan waktu lebih dari 1 detik dan Anda ingin menyebarkan perintah yang dapat Anda coba
Atau, Anda dapat memiliki 5 loop terpisah yang berjalan secara independen, dengan minimum 1 detik.
sumber
Dengan program C,
Misalnya Anda dapat menggunakan utas yang tidur selama 0,2 detik sebentar
gunakan untuk mengetahui cara membuat utas: buat utas (ini adalah tautan yang saya gunakan untuk menempelkan kode ini)
sumber
cc
masih alat Unix yang ada, dan ini bukan banyak kode!Dengan menggunakan node.js Anda dapat memulai utas tunggal yang mengeksekusi skrip bash setiap 200 milidetik tidak peduli berapa lama respons yang diperlukan untuk kembali karena respons datang melalui fungsi callback .
Javascript ini berjalan setiap 200 milidetik dan responsnya didapat melalui fungsi panggilan balik
function (error, stdout, stderr)
.Dengan cara ini Anda dapat mengontrol bahwa itu tidak pernah melebihi 5 panggilan per detik terlepas dari seberapa lambat atau cepat eksekusi perintah atau berapa banyak harus menunggu jawaban.
sumber
Saya telah menggunakan
pv
solusi berbasis Stéphane Chazelas untuk beberapa waktu, tetapi menemukan bahwa itu keluar secara acak (dan diam-diam) setelah beberapa waktu, di mana saja dari beberapa menit hingga beberapa jam. - Sunting: Alasannya adalah skrip PHP saya kadang-kadang mati karena waktu eksekusi maksimal terlampaui, keluar dengan status 255.Jadi saya memutuskan untuk menulis alat baris perintah sederhana yang melakukan apa yang saya butuhkan.
Mencapai tujuan awal saya semudah:
Ini memulai hampir persis 5 perintah per detik, kecuali sudah ada 20 proses bersamaan, dalam hal ini ia melewatkan eksekusi berikutnya hingga slot tersedia.
Alat ini tidak sensitif terhadap status 255.
sumber