1. 程式人生 > >[ SHELL編程 ] shell多線程操作實例

[ SHELL編程 ] shell多線程操作實例

while lee ron clas fifo avg 理解 size 進程數量

1、需求

查找192.168.0.*網段中所有未使用過的IP

2、實現

我們知道查找未使用IP的方法可以使用ping命令完成。對於單個IP的判斷,使用命令如下

$ ping -c 1 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=0.031 ms

--- 192.168.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time
0ms rtt min/avg/max/mdev = 0.031/0.031/0.031/0.000 ms

如果上述類似消息,則判斷該IP是連通的即在使用中。如果沒有,則可以判斷未使用。如果只是查找一個IP,可以多試幾個就知道了,但是這種靠試效率太低,不科學,寫個循環批量查找下。

#!/bin/bash

for i in $(seq 0 255);do
    ip="192.168.0.${i}"
    ping -c 1 ${ip} &>/dev/null
    if [ $? -ne 0 ];then
      printf "${ip} can not reachable\n"
    fi
done

這裏,實現了批量查找192.168.0.*網段內未使用過的IP。但是執行命令的時候你發現執行非常慢(這裏不貼出執行結果,大家可以自己執行感受一下)。顯然,這沒有解決效率的問題。這時你肯定想到了如果使用多進程就可以解決這個問題了。是的。我們看下下面的例子。

#!/bin/bash

MAX_THREAD_NUM=50

for i in $(seq 0 255);do
    ip="192.168.0.${i}"
    (
      ping -c 1 ${ip} &>/dev/null
      [ $? -ne 0 ] && printf "${ip} can not reachable\n
" )& num_ping=`ps -ef | grep "ping" | grep -v grep | wc -l` while [ "${num_ping}" -gt "${MAX_THREAD_NUM}" ];do sleep 1 num_ping=`ps -ef | grep "ping" | grep -v grep | wc -l` done done wait

執行發現效率數倍提升。上述的例子是利用&將進程放到後臺執行,並且通過循環判斷當前ping命令執行的進程數來控制進程數量。這裏MAX_THREAD_NUM設置的為50,考慮ping不太消耗資源可以還可以調整更大。如果是消耗資源多的命令應該將MAX_THREAD_NUM調小。具體根據服務器性能和命令消耗資源情況調整。

還有一種利用文件描述符、read的方法,我們一塊寫下看下,效果是一樣的,例子如下

#!/bin/bash

temp_fifofile="/tmp/$$.fifo"
mkfifo ${temp_fifofile}
exec 5<>${temp_fifofile}
rm ${temp_fifofile}

MAX_THREAD_NUM=50
for ((i=0;i<${MAX_THREAD_NUM};i++));do
  echo
done >&5

for((i=0;i<=255;i++));do
  read -u5
  (
    ip="10.135.17.${i}"
    ping -c 1 ${ip} &>/dev/null
    [ $? -ne 0 ] && printf "${ip} can not reachable\n"
     echo >&5
   )& 
done
wait
exec 5>&-
exit 0

如果是其他需要多進程執行的命令,可以修改一下。根據實際情況選擇這兩種方法之一實現。方法一相對更好理解。

[ SHELL編程 ] shell多線程操作實例