Shell模拟多线程

UPDATE 20180605: 此种方式存在丢任务的情况,用 parallel 命令做多线程更好更简单

shell不能实现多线程,但是可以通过限制几乎同时放入后台执行的进程数量来模拟多线程,从而达到在提高脚本执行效率的同时又不明显增加负载的作用。

Ping脚本的多线程实现

ip.txt中有9个ip,9个线程,调试模式执行结果

执行时间对比

可以看到线程数量正好合适时执行速度比较快。

CMDB内外网错误修正脚本多线程实现

这是工作中的一个实例,我司的IP分为内网和外网,记录在CMDB中,坑爹的CMDB不校验内外网,可以随便填,于是各种乱象,内网写成外网的,外网写成内网的,还有写“内网IP”,“公网”,还有空着啥都不写的。

CMDB中记录的格式是 :ID,对象类型,IP地址,所属机器盘点号,内外网区分,描述,可以导出为csv文件。基于一个规则文件处理导出的csv数据,找出错误的数据,并纠正,然后在导入CMDB系统。

代码实现

优化方案

上面的代码可以解决问题,但是速度太慢了,大约要30分钟。数据总量近10万条,错误的占总数并不多,但是脚本要一条条的去检查然后比对规则。因此如果能把错误的先找出来,在用上面的脚本处理几千条错误的,速度就能快很多。

改用grep,加-v选项,能实现错误的秒级查找,然后用上面的脚本纠错,也是几秒钟的事情,整个过程不到1分钟就能完成。

参考资料

 

4 thoughts on “Shell模拟多线程

  1. 例子

    #!/bin/bash

    chan=$(mktemp -u /tmp/para.$$.XXXXXXXXX)
    mkfifo $chan
    exec 6<>$chan
    rm $chan

    task() {
    echo "$(date) - Start task $1"
    sleep 3
    }

    for i in {0..5};do
    echo
    done >&6

    for i in {0..10};do
    read -u6
    {
    task $i
    echo >&6
    } &
    done

    wait
    exec 6>&-

    • 执行结果

      Fri Jul 16 02:03:59 CST 2021 - Start task 2
      Fri Jul 16 02:03:59 CST 2021 - Start task 0
      Fri Jul 16 02:03:59 CST 2021 - Start task 1
      Fri Jul 16 02:03:59 CST 2021 - Start task 3
      Fri Jul 16 02:03:59 CST 2021 - Start task 4
      Fri Jul 16 02:04:00 CST 2021 - Start task 5
      Fri Jul 16 02:04:03 CST 2021 - Start task 6
      Fri Jul 16 02:04:03 CST 2021 - Start task 7
      Fri Jul 16 02:04:03 CST 2021 - Start task 10
      Fri Jul 16 02:04:03 CST 2021 - Start task 8
      Fri Jul 16 02:04:03 CST 2021 - Start task 9

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注