shell实现队列控制并发执行脚本

在工作中,个人需要用到统计数据的脚本,比如对批量文件过滤关键字进行统计等等,这种需求很常见。默认的shell脚本是串行的,当有大量文件的时候,要进行循环一个个的过滤出来,这个过程需要比较久,效率也比较低。通过查找资料,对脚本进行调整,实现并发执行,具体如下:

#!/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    #创建文件描述符,以可读(<)可写(>)的方式关联管道文件,这时候文件描述符3就有了有名管道文件的所有特性       
    rm -rf /tmp/fd1    #关联后的文件描述符拥有管道文件的所有特性,所以这时候管道文件可以删除,我们留下文件描述符来用就可以了
    for ((i=1;i<=30;i++))    #30这个具体可以根据系统的cpu核数来调整
    do
        echo >&3     #&3代表引用文件描述符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

代码解析以及问题:

1.管道具有存一个读一个,读完一个就少一个,没有则阻塞,放回的可以重复取,这正是队列特性,但是问题是当往管道文件里面放入一段内容,没人取则会阻塞,这样你永远也没办法往管道里面同时放入10段内容(想当与10把药匙),解决这个问题的关键就是文件描述符了。

2.mkfifo /tmp/fd1
创建有名管道文件exec 3<>/tmp/fd1,创建文件描述符3关联管道文件,这时候3这个文件描述符就拥有了管道的所有特性,还具有一个管道不具有的特性:无限存不阻塞,无限取不阻塞,而不用关心管道内是否为空,也不用关心是否有内容写入引用文件描述符: &3可以执行n次echo >&3 往管道里放入n把钥匙

3.两个for循环,第一个for循环10次,相当于在女士公共厕所门口放了10把钥匙,第二个for循环1000次,相当于1000个人来厕所,read -u3相当于取走一把药匙,{}里面最后一行代码echo >&3相当于上完厕所送还药匙。

4.这样就实现了10把药匙控制1000个任务的运行,运行时间为101s,肯定不如方案二快,但是比方案一已经快很多了,这就是队列控制同一时间只有最多10个线程的并发,既提高了效率,又实现了并发控制。

5.创建一个文件描述符exec 3<>/tmp/fd1 不能有空格,代表文件描述符3有可读(<)可写(>)权限,注意,打开的时候可以写在一起,关闭的时候必须分开关,exec 3<&-关闭读,exec 3>&-关闭写。

转自:https://www.cnblogs.com/chenjiahe/p/6268853.html

猜你喜欢

转载自blog.csdn.net/linxi7/article/details/81317704