Saya memiliki skrip bash yang memproses data beberapa tahun, oleh karena itu skrip memerlukan waktu seminggu untuk menyelesaikannya. Untuk mempercepat prosesnya, saya menggunakan multithreading, dengan menjalankan beberapa instance secara paralel (setiap instance = 1 hari data). Setiap instance menempati 1 CPU, jadi saya dapat menjalankan instance sebanyak CPU yang tersedia. Saat saya menjalankan proses di server kuat yang saya bagikan dengan orang lain, suatu saat saya mungkin memiliki lebih banyak atau lebih sedikit CPU yang tersedia. Skrip saya saat ini adalah:
#!/bin/bash
function waitpid {
#Gather the gLABs PID background processes (Maximum processes in
#background as number of CPUs)
NUMPIDS=`jobs -p|awk 'END {print NR}'`
#A while is set because there seems to be a bug in bash that makes
#sometimes the "wait -n" command
#exit even if none of provided PIDs have finished. If this happens,
#the while loops forces the
#script to wait until one of the processes is truly finished
while [ ${NUMPIDS} -ge ${NUMCPUS} ]
do
#Wait for gLAB processes to finish
PIDS="`jobs -p|awk -v ORS=" " '{print}'`"
wait -n ${PIDS} >/dev/null 2>/dev/null
NUMPIDS=`jobs -p|awk 'END {print NR}'`
done
}
NUMPCUS=10
for(...) #Loop for each day
do
day=... #Set current day variable
#Command to execute, put in background
gLAB_linux -input ${day}folder/${day}.input -output ${day)outfolder/${day}.output &
#Wait for any process to finish if NUMCPUS number of processes are running in background
waitpid
done
Oleh karena itu, pertanyaan saya adalah: jika skrip ini berjalan, apakah ada cara untuk mengubah variabel NUMCPUS ke nilai apa pun (misalnya NUMCPUS=23) tanpa menghentikan skrip?. Jika memungkinkan, saya lebih memilih metode yang tidak melibatkan membaca atau menulis ke file (saya ingin mengurangi file sementara menjadi 0 jika memungkinkan). Saya tidak keberatan jika ini adalah proses "retas", seperti metode yang dijelaskan dalam jawaban ini. Sebenarnya, saya mencoba perintah serupa di gdb seperti pada jawaban itu tetapi tidak berhasil, saya mengalami kesalahan berikut di gdb (dan juga membuat proses macet):
(gdb) attach 23865
(gdb) call bind_variable("NUMCPUS",11,0)
'bind_variable' has unknown return type; cast the call to its declared return type
(gdb) call (int)bind_variable("NUMCPUS",11,0)
Program received signal SIGSEGV, Segmentation fault
EDIT1: Beberapa komentar pada skrip:
- gLAB_linux adalah program pemrosesan inti tunggal dan tidak mengetahui variabel NUMCPUS
- Setiap eksekusi gLAB_linux membutuhkan waktu sekitar 5 jam untuk diselesaikan, oleh karena itu skrip bash sebagian besar waktunya tertidur di dalam file
wait -n
. - NUMCPUS harus berupa variabel lokal untuk skrip, karena mungkin ada skrip lain seperti ini yang berjalan secara paralel (hanya mengubah parameter yang diberikan ke gLAB_linux). Oleh karena itu NUMCPUS tidak dapat menjadi variabel lingkungan.
- Satu-satunya proses yang mengakses NUMCPUS adalah skrip bash
EDIT2: Setelah jawaban @Kamil, saya menambahkan proposal saya untuk membaca dari file jumlah CPU
function waitpid {
#Look if there is a file with new number of CPUs
if [ -s "/tmp/numCPUs_$$.txt" ]
then
TMPVAR=$(awk '$1>0 {print "%d",$1} {exit}' "/tmp/numCPUs_$$.txt")
if [ -n "${TMPVAR}" ]
then
NUMCPUS=${TMPVAR}
echo "NUMCPUS=${TMPVAR}"
fi
rm -f "/tmp/numCPUs_$$.txt"
fi
#Gather the gLABs PID background processes (Maximum processes in
#background as number of CPUs)
NUMPIDS=`jobs -p|awk 'END {print NR}'`
#A while is set because there seems to be a bug in bash that makes
#sometimes the "wait -n" command
#exit even if none of provided PIDs have finished. If this happens,
#the while loops forces the
#script to wait until one of the processes is truly finished
while [ ${NUMPIDS} -ge ${NUMCPUS} ]
do
#Wait for gLAB processes to finish
PIDS="`jobs -p|awk -v ORS=" " '{print}'`"
wait -n ${PIDS} >/dev/null 2>/dev/null
NUMPIDS=`jobs -p|awk 'END {print NR}'`
done
}
--limit
dari paralel GNU. - person choroba   schedule 22.11.2018parallel
bisa membaca baris cmd dari stdin. - person georgexsh   schedule 22.11.2018wait -n
:wait -n
menunggu pekerjaan latar belakang berikutnya selesai; berikutnya seperti pada berikutnya semua pekerjaan latar belakang pada sesi saat ini. PID yang ditentukan setelah-n
diabaikan. Anda dapat memverifikasi ini dengansleep 1 & sleep 9 & wait -n $!
.$!
adalah PID darisleep 9
, tetapiwait
hanya akan menunggusleep 1
. - person Socowi   schedule 22.11.2018