shell中没有多进程的概念,能够经过开启子shell并在后台执行来实现并发。
shell
串行执行api
#!/bin/bash start=`date +"%s"` for (( i=0; i<10; i++ )) do { echo "execute" sleep 1 } done end=`date +"%s"` echo "time: " `expr $end - $start`
start=`date +"%s"`
for (( i=0; i<10; i++ ))
do
{
echo "execute"
sleep 1
}
done
end=`date +"%s"`
echo "time: " `expr $end - $start`
执行时间为10秒
bash
并发执行
并发
让for循环中的代码在后台子shell中执行,只需在for循环的结尾加上&,而且在for循环外加上wait语句,等待子进程结束便可。app
#!/bin/bash start=`date +"%s"` for (( i=0; i<10; i++ )) do { echo "execute" sleep 1 }& done wait end=`date +"%s"` echo "time: " `expr $end - $start`
start=`date +"%s"`
for (( i=0; i<10; i++ ))
do
{
echo "execute"
sleep 1
}&
done
wait
end=`date +"%s"`
echo "time: " `expr $end - $start`
执行时间为1秒,速度提高了10倍。
ide
这种方式比较简单,可是有个弊端,没法控制子进程的数量,若是循环一万次,会产生一万个子进程,形成不可预期的状况。
函数
能够经过命名管道来控制子进程的数量
ui
管道能够用于进程间通讯,一个进程向管道中写入数据,同时另外一个进程从管道中读取数据,管道为空进程会被阻塞,只有一个进程读或者一个进程写管道时,进程也会被阻塞。spa
一般使用的 cat | grep name 中的 | 是无名管道。
code
利用命令管道控制并发数量的实例
#!/bin/bash fd_fifo=/tmp/fd_1 mkfifo $fd_fifo #建立命令管道(pipe类型文件) exec 6<>$fd_fifo #将管道的fd与6号fd绑定 proc_num=5 #进程个数 count=0; #预分配资源 for ((i=0;i<$proc_num;i++)) do echo >& 6 #写入一个空行 done start=`date +"%s" for (( i=0; i<10; i++ )) do read -u 6 #读取一个空行 { echo "execute" sleep 1 echo >& 6 #完成任务,写入一个空行 }& #后台执行 done wait #等待全部的任务完成 exec 6>&- #关闭fd 6描述符,stdou和stdin exec 6<&- rm -f $fifo #删除管道 end=`date +"%s"` echo "time: " `expr $end - $start`
x
fd_fifo=/tmp/fd_1
mkfifo $fd_fifo #建立命令管道(pipe类型文件)
exec 6<>$fd_fifo #将管道的fd与6号fd绑定
proc_num=5 #进程个数
count=0;
#预分配资源
for ((i=0;i<$proc_num;i++))
do
echo >& 6 #写入一个空行
done
start=`date +"%s"
for (( i=0; i<10; i++ ))
do
read -u 6 #读取一个空行
{
echo "execute"
sleep 1
echo >& 6 #完成任务,写入一个空行
}& #后台执行
done
wait #等待全部的任务完成
exec 6>&- #关闭fd 6描述符,stdou和stdin
exec 6<&-
rm -f $fifo #删除管道
end=`date +"%s"`
echo "time: " `expr $end - $start`