shell脚本多线程

function thread_func() {
    # 调用哪个函数执行多线程
    executed_func=$1
    [[ -z ${executed_func} ]] && error_exit "调用的函数为空"

    # 传入进来要循环的文件
    list_file=${2}
    [[ ! -s ${list_file} ]] && error_exit "列表文件为空或者文件不存在: ${list_file}"

    # 设置并发的线程数,根据本服务器的CPU核数是最合适的
    CPU_count=$(cat /proc/cpuinfo| grep "processor" | wc -l)
    let thread=${CPU_count}*2-2  # 减2是因为给服务器留点余地
    [[ ${thread} -lt 2 ]] && thread=2
    [[ ${thread} -gt 15 ]] && thread=15 # # 根据自己的情况设置峰值

    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<${list_file}

    while read LINE <&5
    do
    {
        read -u6  # 代表从管道中读取一个令牌
        {   
            ${executed_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

你可能感兴趣的:(shell,大数据)