Contents
3.41. shell实现多并发控制¶
3.41.1. 1.不并发¶
#!/usr/bin/env bash
#usage:xxx
#scripts_name:xxx.sh
shutdown_instance_array=($(nova list | grep SHUTOFF | awk -F "|" '{print $2}'))
shutdown_instance_Name=($(nova list | grep SHUTOFF | awk -F "|" '{print $3}'))
declare -A array_instance
# 设置关联数组
for i in ${!shutdown_instance_array[@]}; do array_instance[${shutdown_instance_Name[$i]}]=${shutdown_instance_array[$i]}; done
name_arry=(${!array_instance[@]}) #key -name
id_arry=(${array_instance[@]}) #value -id
for ((i = 0; i < ${#shutdown_instance_array[@]}; i++)); do
{
# echo ${name_arry[$i]}
map_dev=$(rbd map ${id_arry[$i]}_disk -p vms)
echo -e "xfs_repair -L $map_dev > ${name_arry[$i]}.log 2>&1 &"
} &
sleep 1
done
wait
stop_time=$(date +%s) #定义脚本运行的结束时间
echo "TIME:`expr $stop_time - $start_time`"
3.41.2. 2.控制并发¶
2.1 控制并发示例1¶
#!/usr/bin/env bash
#usage: To repair the virtual machine hard disk, the virtual machine must be off
source /etc/kolla/admin-openrc.sh
start_time=$(date +%s)
Nproc=5
shutdown_instance_array=($(nova list | grep SHUTOFF | awk -F "|" '{print $2}'))
shutdown_instance_Name=($(nova list | grep SHUTOFF | awk -F "|" '{print $3}'))
declare -A array_instance
# 设置关联数组
for i in ${!shutdown_instance_array[@]}; do array_instance[${shutdown_instance_Name[$i]}]=${shutdown_instance_array[$i]}; done
name_arry=(${!array_instance[@]}) #key -name
id_arry=(${array_instance[@]}) #value -id
[ -e /tmp/fifo.$$ ] || mkfifo /tmp/fifo.$$
exec 3<>/tmp/fifo.$$
rm -f /tmp/fifo.$$
for ((i = 0; i < $Nproc; i++)); do
echo >&3
done
for ((i = 0; i < ${#shutdown_instance_array[@]}; i++)); do
{
read -u3
sleep 1
echo "xfs_repair instamceName: ${name_arry[$i]} instamceID: ${id_arry[$i]} "
device_name=$(rbd map ${id_arry[$i]}_disk -p vms)
xfs_repair -L ${device_name} > ${name_arry[$i]}_$$.log 2>&1
echo "instamceName: ${name_arry[$i]} instamceID: ${id_arry[$i]}" >> repairInformationSummary.log
echo >&3 #执行到最后,把令牌放回管道
}&
done
wait
stop_time=$(date +%s)
echo "TIME:$(expr $stop_time - $start_time)"
exec 3<&-
2.2 控制并发示例2¶
#!/usr/bin/env bash
#usage:xxx
#scripts_name:xxx.sh
thread=5
tmp_fifofile=/tmp/$$.fifo
mkfifo $tmp_fifofile
exec 8<> $tmp_fifofile
rm $tmp_fifofile
for i in `seq $thread`
do
echo $i &> 8
done
for i in {1..245}
do
read -u8
{
ip=192.168.122.$i
ping -c1 -W1 $ip &>/dev/null
if [ $? -eq 0 ];then
echo "$ip is down!"
else
echo "$ip is up"
fi
echo $i >& 8
}&
done
wait
exec 8 <&-
echo "all finished......"
2.3 控制并发示例3¶
#!/bin/bash
date
DIR=/test/log/
FILE_NAME=65535_`date +"%Y%m%d"`;
FILE_NAME_LAST_DAY=`date -d "yesterday" +"%Y%m%d"`;
time_of_system=`date +"%Y-%m-%d"`
function multi_processor(){
[ -e /tmp/fd1 ] || mkfifo /tmp/fd1
exec 3<>/tmp/fd1
rm -rf /tmp/fd1
for ((i=1;i<=30;i++))
do
echo >&3
done
for file in $1
do
read -u3
{
grep $3 $file | awk -F"|" '{print $7}' | sort | uniq >> $2;
echo >&3
}&
done
wait
exec 3<&-
exec 3>&-
}
#register 1 day ago
register_file=register_file_1_day_ago_$HOSTNAME.txt
file_modify_time=`stat $register_file | grep Modify | awk '{print $2}'`
files_last_day=`find $DIR -type f -name "$FILE_NAME_LAST_DAY*"`
if [[ $file_modify_time != $time_of_system ]]; then
echo "$register_file file_modify_time(${file_modify_time}) time_of_system(${time_of_system})"
rm $register_file
multi_processor "$files_last_day" "$register_file" "REGISTER"
fi
2.4 控制并发示例4¶
#!/usr/bin/env bash
#usage:xxx
#scripts_name:xxx.sh
# author:xiaojian
Njob=15 #任务总数
Nproc=5 #最大并发进程数
mkfifo ./fifo.$$ && exec 777<> ./fifo.$$ && rm -f ./fifo.$$ #通过文件描述符777访问fifo文件
for ((i=0; i<$Nproc; i++)); do #向fifo文件先填充等于Nproc值的行数
echo "init time add $i" >&777
done
for ((i=0; i<$Njob; i++)); do
{
read -u 777 #从fifo文件读一行
echo "progress $i is sleeping for 3 seconds zzz…"
sleep 3
echo "real time add $(($i+$Nproc))" >&777 #sleep完成后,向fifo文件重新写入一行
} &
done
wait
exec 777 >&-
exec 777 <&-
echo -e "time-consuming: $SECONDS seconds"
2.5 控制并发示例5¶
#!/usr/bin/env bash
#usage:xxx
#scripts_name:${NAME}.sh
# author:xiaojian
CE_HOME="/data/ContentEnginne"
LOG_PATH="/data/logs"
# 控制爬虫数量为8
MAX_SPIDER_COUNT=8
count=`ps -ef|grep -v grep|grep run.py|wc -l`
try_time=0
cd $CE_HOME
while [ $count -lt $MAX_SPIDER_COUNT -a $try_time -lt $MAX_SPIDER_COUNT ]; do
let try_time +=1
python run.py >> ${LOG_PATH}/spider.log 2>&1 &
count=`ps -ef|grep -v grep|grep run.py|wc -l`
done
2.6 控制进程数量的ping脚本¶
#!/bin/bash
#Version:3.0
#功能描述(Description):控制进程数量的ping测试脚本.
#使用wait命令等待所有子进程结束后再退出脚本.
num=10 #控制进程数量.
net="192.168.4"
pipefile="/tmp/multiping_$$.tmp"
multi_ping() {
ping -c2 -i0.2 -W1 $1 &>/dev/null && echo "$1 is up." || echo "$1 is down."
}
#创建命名管道文件,创建其文件描述符,通过重定向导入数据到管道文件中.
mkfifo $pipefile
exec 12<>$pipefile
for i in $(seq $num)
do
echo "" >&12 &
done
#通过循环反复调用函数并将其放入后台并行执行.
#成功读取命名管道中的数据后开启新的进程.
#所有内容读取完后read被阻塞,无法再启动新进程.
#等待前面启动的进程结束后,继续往管道文件中写入数据,释放阻塞,再次开启新的进程.
for j in {1..254}
do
read -u12
{
multi_ping $net.$j
echo "" >&12
} &
done
wait
rm -rf $pipfile