Multitasking dalam skrip shell

Terkadang, saat menulis skrip shell, Anda ingin melakukan beberapa tindakan di beberapa utas. Situasi yang sesuai mungkin, misalnya, mengompresi sejumlah besar file besar pada host multiprosesor, dan mentransfer file melalui bandwidth lebar, di mana kecepatan koneksi individual dibatasi.



Semua contoh ditulis dalam bash, tetapi (dengan sedikit perubahan) akan bekerja dalam ksh. Csh juga memiliki fasilitas manajemen proses latar belakang, sehingga pendekatan serupa dapat digunakan.



KONTROL PEKERJAAN



Ini adalah nama bagian dalam man bash di mana detailnya dijelaskan, jika Anda suka membaca man. Kami menggunakan fitur sederhana berikut:



perintah & - menjalankan perintah di

pekerjaan latar belakang - mencetak daftar perintah latar belakang



Contoh sederhana yang tidak melakukan tindakan berguna. Angka dibaca dari file test.txt, dan 3 proses diluncurkan secara paralel, yang tidur selama jumlah detik yang sesuai. Setiap tiga detik, jumlah proses yang berjalan diperiksa, dan jika ada kurang dari tiga, yang baru akan dimulai. Peluncuran proses latar belakang telah dipindahkan ke fungsi mytask terpisah, tetapi Anda dapat memulainya secara langsung dalam satu putaran.



test.sh
#!/bin/bash 

NJOBS=3 ; export NJOBS

function mytask () {
echo sleeping for $1
 sleep $1
}

for i in $( cat test.txt )
do
    while [  $(jobs | wc -l ) -ge $NJOBS ]
        do 
            sleep 3
        done
    echo executing task for $i
    mytask $i &
done

echo waiting for $( jobs | wc -l ) jobs to complete
wait




Memasukan data:



test.txt
60

50

30

21

12

13



Perhatikan menunggu setelah loop, perintah menunggu proses yang berjalan di latar belakang selesai. Tanpanya, skrip akan segera berhenti setelah loop berakhir dan semua proses latar belakang akan terputus. Mungkin penantian ini disebutkan dalam meme terkenal "oh, tunggu !!!".



Menghentikan proses latar belakang



Jika Anda menghentikan skrip dengan Ctrl-C, skrip akan dimatikan dengan semua proses latar belakang. semua proses yang berjalan di terminal menerima sinyal dari keyboard (misalnya, SIGINT). Jika skrip dimatikan dari terminal lain dengan perintah kill, proses latar belakang akan tetap berjalan hingga penghentian, dan Anda perlu mengingat ini.



Header spoiler
user@somehost ~/tmp2 $ ps -ef | grep -E «test|sleep»

user 1363 775 0 12:31 pts/5 00:00:00 ./test.sh

user 1368 1363 0 12:31 pts/5 00:00:00 ./test.sh

user 1370 1368 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 60

user 1373 1363 0 12:31 pts/5 00:00:00 ./test.sh

user 1375 1373 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 50

user 1378 1363 0 12:31 pts/5 00:00:00 ./test.sh

user 1382 1378 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 30

user 1387 1363 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 3

user 1389 556 0 12:31 pts/2 00:00:00 grep --colour=auto -E test|sleep

user@somehost ~/tmp2 $ kill 1363

user@somehost ~/tmp2 $ ps -ef | grep -E «test|sleep»

user 1368 1 0 12:31 pts/5 00:00:00 ./test.sh

user 1370 1368 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 60

user 1373 1 0 12:31 pts/5 00:00:00 ./test.sh

user 1375 1373 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 50

user 1378 1 0 12:31 pts/5 00:00:00 ./test.sh

user 1382 1378 0 12:31 pts/5 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 30

user 1399 556 0 12:32 pts/2 00:00:00 grep --colour=auto -E test|sleep



Situasi ini dapat ditangani dengan mencegat sinyal yang diperlukan, yang kami tambahkan penangannya di awal skrip:



perangkap
function pids_recursive() {
    cpids=`pgrep -P $1|xargs`
    echo $cpids
    for cpid in $cpids;
       do
          pids_recursive $cpid
       done
}

function kill_me () {
    kill -9 $( pids_recursive $$ | xargs )
    exit 1
}

# 
#trap 'echo trap SIGINT; kill_me ' SIGINT
trap 'echo trap SIGTERM; kill_me' SIGTERM




kill -L menampilkan daftar sinyal yang ada, jika perlu, Anda dapat menambahkan penangan untuk sinyal yang diperlukan.



All Articles