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`