背景:最近有一同事需要对一批文件进行压缩,文件比较大也比较多,希望能同时对多个文件进行压缩,同时还要求同时被压缩的文件的个数
要受控制,可以指定;这样做的目的是为了充分利用系统的资源,又不造成因为竞争资源而降低压缩的效率。为此我专门写了一个SHELL,来完成这个功能。觉得很有意识。所以拿出来和大家分享一下。如果能给大家一点点的启发或者
帮助,那将是我最大的荣幸!
原理:遍历fileList.txt文件(该文件保存着要被压缩的文件的文件名),如果当前正在执行的gzip的数目少于预定值4,则执行gzip命令压缩
文件,如果已经超过预定值4,则休眠10秒钟。利用信号机制,当gzip执行完成的时候会向父进程发SIGCHLD信号,父进程捕获该信号后,将保存
正在执行的GZIP数目的变量runNum的值减一。
代码:
################################################################
#!/bin/bash
set -bm #必须执行该命令,不然会收不到信号
runNum=0
#信号处理函数
function traSIGCHLD(){
echo 'a child exit'
runNum=$((runNum-1))
}
#注册信号处理函数
trap 'traSIGCHLD' SIGCHLD
trap -p
while read line
do
#如果超过4个进程再运行则休眠
if [ $runNum -ge 4 ]
then
echo "$runNum more than 4,will sleep!"
sleep 10 &
wait $!
runNum=$((runNum+1))
#如果低于四个进程在运行则启动新的进程
else
echo "$runNum less than 4,will start new task!"
#这里是要执行的命令
gzip $line &
runNum=$((runNum+1))
fi
done<fileList.txt;
#取消信号注册
trap SIGCHLD
##################################################################
特殊说明:1。 sleep 10 &返回的时候也会向父进程发SIGCHLD信号,从而造成runNum的值被减一。从而使变量runNum不能正确
的反应正在运行的gzip的数目(比正在运行的数目小) ,这会造成真实的正在运行的gzip的数目多于指定的数目4,并且sleep 10 &每返回
一次,就会多一个gzip。这里通过wait $!让主程序等待sleep 10 &的返回,只要它一返回,马上对runNum进行补偿加一;
2。这个是在我测试的代码的基础上做过小小的修改的,没经过测试,所以可能会存在一些问题,但是基本原理是一样的。所以
如果大家想在真实环境使用的话请严格的测试后再使用,以免造成系统事故;