#!/bin/bash
tmpfile=$$.fifo #创建管道名称
mkfifo $tmpfile #创建管道
exec 4<>$tmpfile #创建文件标示4,以读写方式操作管道$tmpfile
rm $tmpfile #将创建的管道文件清除
thred=4 #指定并发个数
seq=(1 2 3 4 5 6 7 8 9 21 22 23 24 25 31 32 33 34 35) #创建任务列表
# 为并发线程创建相应个数的占位
{
for (( i = 1;i<=${thred};i++ ))
do
echo; #因为read命令一次读取一行,一个echo默认输出一个换行符,所以为每个线程输
done
} >&4 #将占位信息写入管道
for id in ${seq[*]} #从任务列表 seq 中按次序获取每一个任务
do
read #读取一行,即fd4中的一个占位符
(./ur_command ${id};echo >&4 ) & #在后台执行任务ur_command 并将任务 ${id} 赋给当前任务;任务执行完后在fd4种写入一个占位符
done <&4 #指定fd4为整个for的标准输入
wait #等待所有在此shell脚本中启动的后台任务完成
exec 4>&- #关闭管道
整个流程中read 和 echo 对fd4的交替写入和读取是并发处理的关键
可以想象 如果read 命令发现fd4中没有数据时 将等待fd4的数据
如果可以自动kill掉超时的子任务就更好了
原文:能不能用shell做一个队列
r2007 回复于:2005-12-24 19:27:15
#!/bin/bash
tmpfile=$$.fifo
mkfifo $tmpfile
exec 4<>$tmpfile
rm $tmpfile #以上工作---开一包间(一楼4号房间)
{ echo;echo;echo;echo; } >&4 #摆一桌麻将,4张椅子
for (( i = 1 ; i <= 100 ; i++ )) #100个赌鬼排队进场
do
read #赌鬼开始抓风,东西南北,拿椅子按次序坐下
( ur_command $i; echo >&4 ) & #开始打牌ing...;bp机响了,是GF的,归还椅子走人
done <&4
wait #等待最后4个赌鬼打完
nees 回复于:2005-12-25 20:32:11
我在linux下测试通过。
另外我写了一种变体,对于参数不是连续的也可以适用,请大家指正:
#!/bin/bash
tmpfile=$$.fifo
mkfifo $tmpfile
exec 4<>$tmpfile
rm $tmpfile #以上工作---开一包间(一楼4号房间)
thred=4
seq=(1 2 3 4 5 6 7 8 9 21 22 23 24 25 31 32 33 34 35)
#
{
for (( i = 1;i<=${thred};i++ ))
do
echo;
done
} >&4
for id in ${seq[*]}
do
read
(./ur_command ${id};echo >&4 ) &
done <&4
wait