ฉันมีสคริปต์ทุบตีที่ประมวลผลข้อมูลหลายปี ดังนั้นสคริปต์อาจใช้เวลาหนึ่งสัปดาห์จึงจะเสร็จสิ้น เพื่อเร่งกระบวนการให้เร็วขึ้น ฉันใช้มัลติเธรดโดยเรียกใช้หลายอินสแตนซ์พร้อมกัน (แต่ละอินสแตนซ์ = ข้อมูล 1 วัน) แต่ละอินสแตนซ์ใช้ CPU 1 ตัว ดังนั้นฉันจึงสามารถเรียกใช้อินสแตนซ์ได้มากเท่าที่มี CPU ขณะที่ฉันกำลังเรียกใช้กระบวนการในเซิร์ฟเวอร์ที่มีประสิทธิภาพซึ่งฉันแบ่งปันกับผู้อื่น ในบางครั้ง ฉันอาจมี CPU ที่พร้อมใช้งานไม่มากก็น้อย สคริปต์ปัจจุบันของฉันคือ:
#!/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
ดังนั้น คำถามของฉันคือ หากสคริปต์นี้ทำงานอยู่ มีวิธีใดที่ฉันสามารถเปลี่ยนตัวแปร NUMCPUS เป็นค่าใดๆ (เช่น NUMCPUS=23) โดยไม่ต้องหยุดสคริปต์ได้ ถ้าเป็นไปได้ ฉันต้องการวิธีที่ไม่เกี่ยวข้องกับการอ่านหรือการเขียนไฟล์ (ฉันต้องการลดไฟล์ชั่วคราวให้เป็น 0 ถ้าเป็นไปได้) ฉันไม่รังเกียจหากมันเป็นกระบวนการ "แฮ็ก" เช่นวิธีที่อธิบายไว้ใน คำตอบนี้ ที่จริงแล้วฉันลองใช้คำสั่งที่คล้ายกันของ gdb เช่นเดียวกับคำตอบนั้น แต่มันใช้งานไม่ได้ ฉันมีข้อผิดพลาดต่อไปนี้ใน gdb (และทำให้กระบวนการขัดข้องด้วย):
(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
แก้ไข 1: ความคิดเห็นบางส่วนต่อสคริปต์:
- gLAB_linux เป็นโปรแกรมประมวลผลแกนเดียวและไม่ทราบถึงตัวแปร NUMCPUS
- การดำเนินการ gLAB_linux แต่ละครั้งจะใช้เวลาประมาณ 5 ชั่วโมงจึงจะเสร็จสิ้น ดังนั้นสคริปต์ทุบตีจึงใช้เวลาส่วนใหญ่อยู่ใน
wait -n
- NUMCPUS ต้องเป็นตัวแปรท้องถิ่นสำหรับสคริปต์ เนื่องจากอาจมีสคริปต์อื่นที่มีลักษณะเช่นนี้ทำงานแบบขนาน (เปลี่ยนเฉพาะพารามิเตอร์ที่กำหนดให้กับ gLAB_linux) ดังนั้น NUMCPUS จึงไม่สามารถเป็นตัวแปรสภาพแวดล้อมได้
- กระบวนการเดียวในการเข้าถึง NUMCPUS คือสคริปต์ทุบตี
แก้ไข 2: หลังจาก @Kamil ตอบ ฉันเพิ่มข้อเสนอสำหรับการอ่านจำนวน 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
ของ GNU แบบขนาน - person choroba   schedule 22.11.2018parallel
สามารถอ่านบรรทัด cmd จาก stdin - person georgexsh   schedule 22.11.2018wait -n
:wait -n
รอให้งานพื้นหลังถัดไปเสร็จสิ้น ถัดไป เช่นเดียวกับใน ถัดไปของงานพื้นหลังทั้งหมดของเซสชันปัจจุบัน PID ที่ระบุหลัง-n
จะถูกละเว้น คุณสามารถตรวจสอบสิ่งนี้ได้ด้วยsleep 1 & sleep 9 & wait -n $!
$!
คือ PID ของsleep 9
แต่wait
จะรอเพียงsleep 1
เท่านั้น - person Socowi   schedule 22.11.2018