LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2140|回复: 9

[求助]bash脚本批处理如何按顺序同时运行2个任务

[复制链接]
发表于 2008-10-20 20:37:18 | 显示全部楼层 |阅读模式
比如,有50个job,都是命令行的,都是单CPU的。
在双核下,想一次跑两个。

直接写50行,结尾加 & 就成了50个一起跑,如何一次只跑2个?

由于每个job耗时不同,我希望是谁先干完就把下一个job接着启动,如果每两行加个wait常常会一个job干完了,另一个还在慢慢跑。

不需要事先考虑job耗时,直接一个个接着跑就行了。

直接用bash可以吗?或者要装什么软件?
发表于 2008-10-21 13:53:46 | 显示全部楼层
比较接近的方法,写两个脚本
a.sh
run 25 task

main.sh
a.sh &
a.sh &
wait
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-10-22 23:51:23 | 显示全部楼层
没有其他方法吗?
回复 支持 反对

使用道具 举报

发表于 2008-10-23 08:37:33 | 显示全部楼层
if job1;then
job2
else
job2
fi

这样job2在job1返回后才执行。这样是顺序执行吗?
回复 支持 反对

使用道具 举报

发表于 2008-10-23 12:17:22 | 显示全部楼层
#!/bin/sh
jobs = ( job1 job2 job3 )
jobid = 0

while true; do
if [ $(ps axl |awk '{print $4}'|grep $$|wc -l) -lt 2 ] && [ $jobid -le ${#jobs} ]; then
sh ${jobs[$jobid]}
(( jobid ++ ))
else
break
fi
sleep 20
done;

这样行不??
没有测试过,应该要改一下才可以用
回复 支持 反对

使用道具 举报

发表于 2008-10-23 13:00:21 | 显示全部楼层
如果每一个 job 都对应一个 .sh 文件, 并且它们都放置于 jobs/ 目录下的话

  1. # Makefile
  2. jobs := $(wildcard jobs/*.sh)
  3. marks := $(jobs:.sh=.mark)

  4. all: $(marks)

  5. %.mark: %.sh
  6.     sh $<
  7.     touch $@
复制代码

然后 make -j2
回复 支持 反对

使用道具 举报

发表于 2008-10-23 23:20:24 | 显示全部楼层

不知道这个主意可不可行

我有个主意,但不知可实现否

把50个job写在一个文件中,一行一个

然后同时开始两个循环,两个循环的行为是一样的,先从文件中取出一行并同时从文件中把这行删除(一气呵成,避免两个循环取到相同的行),然后执行,然后再取一行,再执行。

代码不会写,不知道能不能实现
回复 支持 反对

使用道具 举报

发表于 2008-10-24 11:18:56 | 显示全部楼层
#!/bin/sh


function lock
{
    while ! mkdir $1 2> /dev/null;
    do
        dd bs=1 count=1 <& 3 > /dev/null 2>/dev/null;
    done;
}

function unlock
{
    if ! rmdir $1;
    then
        echo "bad call unlock";
    fi;
    dd bs=1 count=1 >& 4 < /dev/zero 2>/dev/null;
}

function gotter
{
    let use_idx=0;
    exec 3<_sleep;
    exec 4>_wakeup;
    lock _lock;
    export use_idx=`cat _refcount`;
    while [ $use_idx -lt 1000 ];
    do
        echo $(($use_idx+1)) > _refcount;
        unlock _lock;
        echo $1.lock $use_idx;
    sleep 1;
           lock _lock;
           export use_idx=`cat _refcount`;
    done;
    rmdir $1.lock;
    unlock _lock;
    exec 4>&-;
    exec 3<&-;
    echo $1.lock is finish
}

rm -f _lock;
echo 0 > _refcount;
mkfifo _wakeup _sleep;

#start cotask a b c d e f
for i in a b c d e f;
do
    mkdir $i.lock;
    (gotter $i &);
done;

exec 3>_sleep;
exec 4<_wakeup;

#wait for cotask finish a b c d e f
for i in a b c d e f;
do
    while [ -d $i.lock ];
    do
        dd bs=1 count=1 >&3 <&4 2>/dev/null;
    done;
done;

exec 4<&-
exec 3<&-

rm _sleep _wakeup;
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-10-26 23:39:26 | 显示全部楼层
看上去还是调用make来得方便。不过我是参数执行的,两的程序有先后依赖关系,然后对一堆数据做统计。估计写makefile还有翻半天……

直接用bash搞加锁机制的,我只看个半懂。作为学习还是很有用的。

谢谢楼上各位。
回复 支持 反对

使用道具 举报

发表于 2008-10-27 12:58:58 | 显示全部楼层
有先后依赖关系的用 make 就更方便了, 比如在上面那个脚本中, 再加入

  1. jobs/job001.mark: jobs/job002.mark jobs/job003.mark
复制代码

这一行就可以确保 job001.sh 在 job002.sh 和 job003.sh 都执行成功完毕后再执行.

至于参数, 这里的 jobs/*.sh 都只做为 wrapper 就好了呀, 具体要执行什么, 怎么执行, 写到对应的脚本里就好了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表