Bash脚本的批量作业
前言
其实这个博文很短,就是记录下今天下午写的bash代码。所有完成的工作的目的就是实现对于研究做服务器集群的使用。
需求说明
- 首先实验室的服务器不同于前面的深圳超算中心代码,深圳超算是可以疯狂提交,因为后台的作业调度系统自动帮助你进行调度。一次一个核的安排。我的任务就是只使用一个核,但是需要同时计算很多任务,比如50个。
 - 实验室服务器性能比较好,但是一个节点只有15个核,但是当提交多于15个任务的时候就会出现性能的下降。所以我的任务要求就是可以控制总任务量比如50个任务,保持运行任务数目为15个,一个任务结束,另外一个任务自动开启。
 - 可以后台运行,这样方便我关闭机器,回头再查看任务结果。
 
bash脚本
网上发现一个非常好的脚本,Bash脚本实现批量作业并行化
基本上,整体的代码都是参考的作者的实现只是修改了CMD这个函数部分。
#!/bin/sh
Possibility="step10"
date="20150602"
prog="chanel8.3.1"
mkdir ~/run/${date}/${Possibility}
Njob=50    # 作业数目
Nproc=3    # 可同时运行的最大作业数
function CMD {        # 测试命令, 随机等待几秒钟
    mkdir ~/run/${date}/${Possibility}/no$1
    cd ~/run/${date}/${Possibility}/no$1
    cp ~/run/${date}/${prog} .
	./${prog}>record    
}
Pfifo="/tmp/$$.fifo"   # 以PID为名, 防止创建命名管道时与已有文件重名,从而失败
mkfifo $Pfifo          # 创建命名管道
exec 6<>$Pfifo         # 以读写方式打开命名管道, 文件标识符fd为6
                       # fd可取除0, 1, 2,5外0-9中的任意数字
rm -f $Pfifo           # 删除文件, 也可不删除, 不影响后面操作
# 在fd6中放置$Nproc个空行作为令牌
for((i=1; i<=$Nproc; i++)); do
	echo
done >&6
for((i=1; i<=$Njob; i++)); do  # 依次提交作业
	read -u6                   # 领取令牌, 即从fd6中读取行, 每次一行
                               # 对管道,读一行便少一行,每次只能读取一行
                               # 所有行读取完毕, 执行挂起, 直到管道再次有可读行
                               # 因此实现了进程数量控制
	{                          # 要批量执行的命令放在大括号内, 后台运行
		CMD $i && {            # 可使用判断子进程成功与否的语句
			echo "Job $i finished"
		} || {
			echo "Job $i error"
		}
		sleep 1     # 暂停1秒,可根据需要适当延长,
                    # 关键点,给系统缓冲时间,达到限制并行进程数量的作用
		echo >&6    # 归还令牌, 即进程结束后,再写入一行,使挂起的循环继续执行
	} &
done
wait                # 等待所有的后台子进程结束
exec 6>&-           # 删除文件标识符
然后用这个方式运行,bash test3.sh > log &
后面的”&”号一定要加上,这样这个脚本就转入后台运行,可以更加方便。
然后top查看下运行的进程,确保脚本启动成功。

    Written on June 16, 2015
  
  
