12 12
发新话题
打印

shell里如何实现‘多线程’?

本主题由 dearvoid 于 2008-6-25 11:39 加入精华

shell里如何实现‘多线程’?

即比如我有100个可执行文件,互相间没有特别的先后执行关系,如
复制内容到剪贴板
代码:
job_1
job_2
job_2
.....
job_100
想用csh/bash来多线程调用执行
比如一次开5个线程,那么job_1,2,3,4,5一起先开始,那么其中任何一个线程如果先执行完成,则继续执行下一个没有初执行过的文件,如job_6,7,8....,这样一直以所指定的线程数来执行所有100个文件。
我本来想用 "&" 来放入后台,可是这样我一次可以指定5放入后台,但是无法知道其中任何一个程序何时执行完毕,所以也无法继续执行下一个程序啊!

[ 本帖最后由 dearvoid 于 2008-6-25 13:10 编辑 ]      
问世间、情是何物? 直教生死相许。 天南地北双飞客, 老翅几回寒暑。 双乐去,离别苦, 就中更有痴儿女。 君应有语, 渺万里层云, 千山暮雪, 只影为谁去?

TOP

完美解决方案
引用:
-(dearvoid@LinuxEden:Forum)-(~/tmp)-
[$$=6718 $?=0]
; cat job_1
#!/bin/bash

n=$((RANDOM % 5 + 1))
echo "$0 sleeping for $n seconds ..."
sleep $n
echo "$0 exiting ..."
-(dearvoid@LinuxEden:Forum)-(~/tmp)-
[$$=6718 $?=0]
; for ((i = 2; i <= 10; ++i)); do cp job_1 job_$i; done
-(dearvoid@LinuxEden:Forum)-(~/tmp)-
[$$=6718 $?=0]
; cat jobs.sh
#!/bin/bash

nParellel=5
nJobs=10
sJobPattern='./job_%d'

aJobs=()
sNextJob=
for ((iNextJob = 1; iNextJob <= nJobs; )); do
    for ((iJob = 0; iJob < nParellel; ++iJob)); do
        if [ $iNextJob -gt $nJobs ]; then
            break;
        fi

        if [ ! "${aJobs[iJob]}" ] || ! kill -0 ${aJobs[iJob]} 2> /dev/null; then
            printf -v sNextJob "$sJobPattern" $((iNextJob++))
            echo "$sNextJob starting ..."
            $sNextJob &
            aJobs[iJob]=$!
        fi
    done
    sleep .1
done

wait
-(dearvoid@LinuxEden:Forum)-(~/tmp)-
[$$=6718 $?=0]
; ./jobs.sh
./job_1 starting ...
./job_1 sleeping for 3 seconds ...
./job_2 starting ...
./job_2 sleeping for 2 seconds ...
./job_3 starting ...
./job_3 sleeping for 5 seconds ...
./job_4 starting ...
./job_5 starting ...
./job_4 sleeping for 4 seconds ...
./job_5 sleeping for 2 seconds ...
./job_2 exiting ...
./job_6 starting ...
./job_6 sleeping for 2 seconds ...
./job_5 exiting ...
./job_7 starting ...
./job_7 sleeping for 1 seconds ...
./job_1 exiting ...
./job_8 starting ...
./job_8 sleeping for 3 seconds ...
./job_7 exiting ...
./job_9 starting ...
./job_9 sleeping for 5 seconds ...
./job_4 exiting ...
./job_6 exiting ...
./job_10 starting ...
./job_10 sleeping for 5 seconds ...
./job_3 exiting ...
./job_8 exiting ...
./job_9 exiting ...
./job_10 exiting ...
-(dearvoid@LinuxEden:Forum)-(~/tmp)-
[$$=6718 $?=0]
; bye
[ 本帖最后由 dearvoid 于 2008-6-25 12:26 编辑 ]      
'
◆ 发帖时请【突出主题】, 以便您的问题能够及时得到回复
◆ 发帖时请将您的【代码】或者【脚本】写在 [code] 和 [/code] 中间

TOP

no response       
'
◆ 发帖时请【突出主题】, 以便您的问题能够及时得到回复
◆ 发帖时请将您的【代码】或者【脚本】写在 [code] 和 [/code] 中间

TOP

不好意思,没想到老大反应这么快
是我反应迟钝了,呵呵      
问世间、情是何物? 直教生死相许。 天南地北双飞客, 老翅几回寒暑。 双乐去,离别苦, 就中更有痴儿女。 君应有语, 渺万里层云, 千山暮雪, 只影为谁去?

TOP

不好意思,刚才是我输入出错了,打错字了,呵呵,sorry

有些地方没看懂啊,还请指教一下
1. 第6行, aJobs=()是什么意思,声明一个空函数?
2. ${aJobs[iJob]} 是取aJobs的PID吗?
3.  aJobs[iJob]=$! 也不知道是什么意思

能否稍微解释一下,谢谢!

BTW,刚才执行了一下,很好用,谢谢了

[ 本帖最后由 mygod100 于 2008-6-25 10:44 编辑 ]      
问世间、情是何物? 直教生死相许。 天南地北双飞客, 老翅几回寒暑。 双乐去,离别苦, 就中更有痴儿女。 君应有语, 渺万里层云, 千山暮雪, 只影为谁去?

TOP

再请教一下,我用 printf -v sNextJob "$sJobPattern" $((iNextJob++)) 好像有问题
好像说没有-v参数,是不是版本不一样啊
我的是
printf 5.2.1                     August 2006      
问世间、情是何物? 直教生死相许。 天南地北双飞客, 老翅几回寒暑。 双乐去,离别苦, 就中更有痴儿女。 君应有语, 渺万里层云, 千山暮雪, 只影为谁去?

TOP

printf 是 bash 的内部命令, -v 参数好像从 bash 3.1 开始才支持      
'
◆ 发帖时请【突出主题】, 以便您的问题能够及时得到回复
◆ 发帖时请将您的【代码】或者【脚本】写在 [code] 和 [/code] 中间

TOP

哦,怪不得我的-v不行了,原来我的是3.0,不过被我改成直接赋值了
sNextJob=./job_$((iNextJob++))
呵呵      
问世间、情是何物? 直教生死相许。 天南地北双飞客, 老翅几回寒暑。 双乐去,离别苦, 就中更有痴儿女。 君应有语, 渺万里层云, 千山暮雪, 只影为谁去?

TOP

有些地方没看懂啊,还请指教一下
1. 第6行, aJobs=()是什么意思,声明一个空函数?
2. ${aJobs[iJob]} 是取aJobs的PID吗?
3.  aJobs[iJob]=$! 也不知道是什么意思

能否稍微解释一下,谢谢!      
问世间、情是何物? 直教生死相许。 天南地北双飞客, 老翅几回寒暑。 双乐去,离别苦, 就中更有痴儿女。 君应有语, 渺万里层云, 千山暮雪, 只影为谁去?

TOP

引用:
原帖由 mygod100 于 2008.6.25 11:21 发表
有些地方没看懂啊,还请指教一下
1. 第6行, aJobs=()是什么意思,声明一个空函数?
2. ${aJobs} 是取aJobs的PID吗?
3.  aJobs=$! 也不知道是什么意思

能否稍微解释一下,谢谢!
1. aJobs=() 是定义一个数组
2. aJobs 数组里面存的是进程的 PID
3. $! 是最近一个后台运行的进程的 PID      
'
◆ 发帖时请【突出主题】, 以便您的问题能够及时得到回复
◆ 发帖时请将您的【代码】或者【脚本】写在 [code] 和 [/code] 中间

TOP

 12 12
发新话题