關於bash如何進行並發執行!
for i in `cat ip.txt`; do
# To do something...
echo $?
done
但是這樣的模版有個問題,在機器數量比較少的時候,還能取得比較滿意的效果。但是如果試想一下!當ip.txt中的主機數量上百,而To do something又是一個比較耗時的操作的時候,這樣的腳本運行一次可能需要的時間就不是一小會了。雖然我們可以盯著屏幕,看著自己寫的腳本平穩地運行,心情也會很好。但是這樣長時間的等待畢竟是一件不能令人愉快的事情。這個時候我們就在想,能不能對腳本做並發呢?讓系統對每一個To do something都同時運行呢。這樣在一定範圍數量內的運行時間就非常令人可觀了(為什麽是一定範圍數量呢?後面會解釋)!其實我們可以用這樣的代碼片段來代替上面的:
for i in `cat ip.txt`; do
{
# To do something
echo $?
} &
done
如此一來,腳本的運行就會針對每一次循環開啟一個子shell進行運算了。時間上也會節省很多。下面是一個ping的例子。
假如我有10臺主機,ip地址都寫在ip.txt中,然後我要對這些主機每一臺進行:ping -c 5 <ip_address>,那麽我可以這麽寫。
for i in `cat ip.txt`; do
{
ping -c 5 $i
echo $?
} &
done
如果我還用原來的方式進行ping的話,可能需要用到將近50秒左右的時間,但是如果放在並發裏面的話時間就會縮短到5秒左右。這樣看來是比較理想的情況了,但是我們在繼續想一下(呵呵,運維的工作的復雜度是和機器數量成正比的^_^!),如果此時有500臺機器要ping怎麽辦?我們還用上面的並發代碼片段就會有問題了。我猜想運行的時候系統可能會變的很慢,因為系統要開500個子shell來完成這些工作。所以下面我們需要控制同時並發的數量,不能讓系統同時運行太多的子shell。網上看到有一些用管道做的,但是感覺太復雜(呵呵,主要是自己沒看懂),其實我們可以這樣考慮,不妨把上面的並發代碼段看成是一個類似進程池的東西,我們把:for i in `cat ip.txt`部分改造成為一個固定次數的循環,然後增加一個數組,每次往這個數組中放置好ip,然後用循環處理,看起來應該是這個樣子:
a=(ip1 ip2 ip3 ip4 ip5)
for ((i=0; i<5; i++)); do
{
ping -c 5 ${a[i]}
echo $?
} &
done
然後每次讀取ip.txt中的5個ip後再調用這個代碼片段。這樣每次就控制在5個進程了,應該不會導致系統卡住或者很慢。
本文出自 “Linux Oracle MariaDB” 博客,請務必保留此出處http://wangergui.blog.51cto.com/8504247/1926853
關於bash如何進行並發執行!