Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux Bash-脚本在长时间运行时,CPU使用率从3%提高到100%_Linux_Bash_Cpu_Cpu Usage - Fatal编程技术网

Linux Bash-脚本在长时间运行时,CPU使用率从3%提高到100%

Linux Bash-脚本在长时间运行时,CPU使用率从3%提高到100%,linux,bash,cpu,cpu-usage,Linux,Bash,Cpu,Cpu Usage,我写了一个脚本,收集了一些系统统计数据。这与压力测试一起运行,以便可以收集有关系统的SAT。收集的统计数据包括CPU使用率(使用sar)、内存使用率(使用空闲)、中断等。通过将收集到的每个数据点放在后台,将其生成到单独的进程中。要将此数据移动到csv文件,以便可以在电子表格中打开,需要进行一些后期处理。后处理也发生在派生的进程中。脚本在采集的样本之间有睡眠间隔。但是,后台进程在此时间间隔内仍在运行 我观察到,当这个脚本运行很长时间时,仅这个脚本的CPU使用率就从3%左右逐渐增加到几乎100%。这

我写了一个脚本,收集了一些系统统计数据。这与压力测试一起运行,以便可以收集有关系统的SAT。收集的统计数据包括CPU使用率(使用sar)、内存使用率(使用空闲)、中断等。通过将收集到的每个数据点放在后台,将其生成到单独的进程中。要将此数据移动到csv文件,以便可以在电子表格中打开,需要进行一些后期处理。后处理也发生在派生的进程中。脚本在采集的样本之间有睡眠间隔。但是,后台进程在此时间间隔内仍在运行

我观察到,当这个脚本运行很长时间时,仅这个脚本的CPU使用率就从3%左右逐渐增加到几乎100%。这是一个令人不安的场景,因为不能允许分析脚本占用如此多的CPU时间。(我使用“top”记录每个进程的CPU使用情况)

另一个有趣的观察结果是,在压力测试中运行的重载进程占用的CPU时间比该脚本少(在其使用率超过90%之后)

如何解决这个问题?我有什么遗漏吗?请指教

在下面添加一些代码位。下面是主循环

while true
do

    if [ $exitstatus = 0 ]
    then
        exitScript
    fi
    let itr++
    echo -e "\n Interation: $itr\n"

    if [ "$3" = "ALL" ]
    then
        export CALC_INTERRUPTS=1
        printTitle "sar"
        processCommand "sar" &

        #printTitle "free"
        processCommand "free" &

        printTitle "interrupts"
        processCommand "interrupts" &

        printTitle "underflows"
        processCommand "underflows" &


        #printTitle "clocktree"
        processCommand "clocktree" &

    else    
        if [ $itr -eq 1 ]
        then
            shift 2
        fi
        for com in "$@"
        do
            printTitle "$com"
            processCommand "$com" &

        done
    fi
    #printTimestamp > $TEMP_LOC/sys.log
    cat /var/log/syslog > $TEMP_LOC/sys.log
    if [ $exitstatus = 0 ]
    then
        exitScript
    fi
    sleep $interval
    #Wait for background jobs from the last iteration to finish     
    for job in `jobs -p`
    do      
        wait $job 
    done

    cat $TEMP_LOC/*.temp >> $TEMP_LOC/monitor.log
    rm -f $TEMP_LOC/*.temp

    if [ $(($itr % 180)) -eq 0 ] 
    then
        takeDump
    fi

done
fi

以下是CPU使用情况的记录和后处理(使用sar)——

processCommand()
{
案件“$1”
(合成孔径雷达)
打印时间戳>>$TEMP\u LOC/$1.TEMP
#echo-n“记录CPU统计信息……”
exe=“sar-P ALL 1”
$exe>$TEMP\u LOC/TEMP\u sar
echo-e“\n\n使用超过1%CPU时间的进程:”>>$TEMP\u LOC/$1.TEMP
顶部-b-n 1>$TEMP\U LOC/TEMP\U top
#删除除当前CPU统计信息之外的所有行
sed-i“5,8!d”$TEMP_LOC/TEMP_sar
#用逗号替换所有空格
sed-i的/[:space:][]\+/,/g'$TEMP\u LOC/TEMP\u sar
Cpu=0
而[-s$TEMP_LOC/TEMP_sar]
做
#如果文件不存在,则添加标题
如果[!-f$TEMP\U LOC/Cpu$Cpu.csv]
然后
printf“时间,$Cpu.us,$Cpu.ni,$Cpu.sy,$Cpu.wa,$Cpu.st,$Cpu.id,$Cpu.total\n”>>$TEMP\u LOC/Cpu$Cpu.csv
fi
#删除CPU号
统计数据=`sed-n'1p'$TEMP_LOC/TEMP_sar | cut-d','--补码-f2`
空闲=`echo$stats | cut-d','-f7`
#将CPU总使用率计算为100空闲
总使用率=$(bc$TEMP\U LOC/Cpu$Cpu.csv
sed-i'1d'$TEMP_LOC/TEMP_sar
让Cpu++
完成
;;

代码的其他部分也起着类似的作用。定期拍摄该参数的快照并对其进行一些后处理。

尝试在/proc“files”上使用单个awk,而不是使用多种工具,如free、sar、ps-C


使用一个脚本而不在shell上保留变量,可以避免一些内存/cpu泄漏,比如在每个循环中忘记清理的shell变量,然后在上面执行grep操作。

可以发布脚本内容吗?是否将所有数据保留在内存中?是否覆盖CSV文件或只是添加新数据?面积逐渐增加ds?还要注意,总CPU%是CPU%/CPU核心数。@choroba,是的,所有数据都在内存中。我挂载了RAMFS并保留了所有的临时数据。@krampstudio,脚本非常大(大约500行左右)。你想让我粘贴整个内容吗?内存泄漏会导致CPU使用率峰值吗?不会。但是如果此shell脚本的内存正在增长,可能会显示一些一直在使用的变量,而不进行清理,并操纵巨大的变量,CPU使用率峰值是否为ps。对不起,可怜的英国汉克斯·布伦诺桑。将尝试相同的:)
processCommand()
{

case "$1" in
sar)
    printTimestamp>> $TEMP_LOC/$1.temp
    #echo -n " Logging CPU stats............ "
    exe="sar -P ALL 1 1"
    $exe > $TEMP_LOC/temp_sar

    echo -e "\n\n Processes using more than 1% of CPU time: " >> $TEMP_LOC/$1.temp
    top -b -n 1 > $TEMP_LOC/temp_top



    #delete all lines except current CPU statistics
    sed -i "5,8! d" $TEMP_LOC/temp_sar
    #replace all spaces with commas
    sed -i  's/[[:space:]]\+/,/g' $TEMP_LOC/temp_sar

    Cpu=0
    while [ -s $TEMP_LOC/temp_sar ]
    do
        #if file does not exist then add the header 
        if [ ! -f $TEMP_LOC/Cpu$Cpu.csv ]
        then
            printf "time,$Cpu.us,$Cpu.ni,$Cpu.sy,$Cpu.wa,$Cpu.st,$Cpu.id,$Cpu.total\n"  >> $TEMP_LOC/Cpu$Cpu.csv
        fi
        #remove  CPU number 
        stats=`sed -n '1p' $TEMP_LOC/temp_sar | cut -d ',' --complement -f 2`

        idle=`echo $stats | cut -d ',' -f 7`
        #calculate totale CPU usage as 100-idle
        total_usage=$(bc <<< "100.00-$idle")
        echo "$stats,$total_usage" >> $TEMP_LOC/Cpu$Cpu.csv

        sed -i '1d' $TEMP_LOC/temp_sar
        let Cpu++

    done

    ;;
time awk ' /MemTotal/ {print $2}; /SwapCached/ {print $2}; /processor/ {print $NF}' /proc/meminfo /proc/cpuinfo 
1933536
17840
0
1

real    0m0.002s
user    0m0.000s
sys 0m0.000s