shell脚本多线程

function thread_func() {
    execute_func=${1}  # 执行的函数
    ip_list=${2}       # 要执行的IP列表
    # 设置并发的线程数,根据本服务器的CPU核数是最合适的
    CPU_count=$(cat /proc/cpuinfo| grep "processor"| wc -l)
    let thread=${CPU_count}*2
    [[ ${thread} -le 2 ]] && thread=2
    [[ ${thread} -ge 10 ]] && thread=10  # 根据自己的情况设置峰值

    tempfifo="my_temp_fifo"
    mkfifo ${tempfifo}      #创建文件描述符文件
    # 使文件描述符为非阻塞式
    exec 6<>${tempfifo}   #创建文件描述符,以可读(<)可写(>)的方式关联管道文件,这时候文件描述符3就有了有名管道文件的所有特性
    rm -f ${tempfifo}     #关联后的文件描述符拥有管道文件的所有特性,所以这时候管道文件可以删除,我们留下文件述符来用就可以了

    # 为文件描述符创建占位信息
    for ((Multithreading=1;Multithreading<=${thread};Multithreading++))
    do {
        echo -ne "\n" 1>&6
    }
    done >&6

    #读取参数列表文件
    exec 5<${ip_list}

    while read LINE <&5
    do
    {
        read -u6  #代表从管道中读取一个令牌
        {
            ${execute_func} $LINE

            echo -ne "\n" 1>&6  #代表执行到最后,读取下一个管道中一个令牌

        } &
    }
    done

    wait   #等待所有任务执行完退出线程任务

    # 关闭fd6管道
    exec 6>&-  #关闭文件描述符的写
    exec 6<&-  #关闭文件描述符的读
}


function ls_server() {
    IP=$1
    ${SSH} 22 ${IP} 'ls /root/'
    [[ $? -ne 0 ]] && echo "服务器(${IP})ls失败" > logs/error.log && return 1
}

function rm_server() {
    IP=$1
    ${SSH} 22 ${IP} 'rm /root/test.txt'
    [[ $? -ne 0 ]] && echo "服务器(${IP})rm失败" > logs/error.log && return 1
}

thread_func ls_server tmp/ip_list.txt
grep '失败' logs/error.log
[[ $? -eq 0 ]] && exit 1

thread_func rm_server tmp/ip_list.txt
grep '失败' logs/error.log
[[ $? -eq 0 ]] && exit 1


版权声明:本文为moyuanbomo原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。