shell编程之九(多线程并发控制)

shell多线程的必要性:

    #shell执行方式:顺序执行,等待前一个完成后,再开始下一条命令
    #缺点:串行顺序执行,时间长,不能合理利用系统资源

案例:打印1到10的数字,每隔一秒钟打印一个(一般实现方式)

A、脚本内容如下:
#/bin/bash
all_num=10
echo -e "开始时间:\t$(date +"%Y-%m-%d %H:%M:%S")"
for num in `seq 1 ${all_num}`
    do
        sleep 1
        echo ${num}
    done
echo -e "结束时间:\t$(date +"%Y-%m-%d %H:%M:%S")"

B、执行结果如下:
开始时间:   2023-05-08 23:47:22
1
2
3
4
5
6
7
8
9
10
结束时间:   2023-05-08 23:47:32

多线程方案一:使用&将正在执行的命令放入后台,并重新开启新的shell执行任务

#实现方式:
    在linux中,在命令的末尾加上&符号,则表示该命令将在后台执行,这样后面的命令不用等待前面的命令执行完就可以开始执行了。
示例中的循环体内有多条命令,则可以用{}括起来,在大括号后面添加&符号

#缺点:不能保证结果按执行命令的次序输出,即输出次序不可控,并且会出现多循环体乱序的情况

A、脚本内容如下:
#/bin/bash
all_num=10
echo -e "开始时间:\t$(date +"%Y-%m-%d %H:%M:%S")"
for num in `seq 1 ${all_num}`
    do
        {
        sleep 1
        echo -e "${num}  时间:$(date +"%Y-%m-%d %H:%M:%S")"
        } &
    done
echo -e "结束时间:\t$(date +"%Y-%m-%d %H:%M:%S")"

B、执行结果如下:(执行时间都是一样的说明,确实是并行执行的)
root@C20230507234325:~# ./test.sh 
开始时间:   2023-05-08 23:53:37
结束时间:   2023-05-08 23:53:37
root@C20230507234325:~# 2  时间:2023-05-08 23:53:38
7  时间:2023-05-08 23:53:38
4  时间:2023-05-08 23:53:38
1  时间:2023-05-08 23:53:38
5  时间:2023-05-08 23:53:38
3  时间:2023-05-08 23:53:38
10  时间:2023-05-08 23:53:38
6  时间:2023-05-08 23:53:38
8  时间:2023-05-08 23:53:38
9  时间:2023-05-08 23:53:38

多线程方案二:命令后台运行+wait命令

#实现原理(及缺点):
    虽说能保证多个循环体之间不会乱序,但是每个循环体内的依然存在乱序的情况
    因为&使得所有循环体内的命令全部进入后台运行,那么倘若循环的次数很多,会使操作系统在瞬间创建出所有的子进程,这会非常消耗系统的资源。
    如果循环体内的命令又很消耗系统资源,则结果可想而知

A、脚本内容如下:
#/bin/bash
all_num=10
echo -e "开始时间:\t$(date +"%Y-%m-%d %H:%M:%S")"
for num in `seq 1 ${all_num}`
    do
        {
        sleep 1
        echo -e "${num}  时间:$(date +"%Y-%m-%d %H:%M:%S")"
        } &         
    done
    wait
echo -e "结束时间:\t$(date +"%Y-%m-%d %H:%M:%S")"

B、执行结果如下:(说明成功并行执行)
开始时间:   2023-05-08 23:57:22
2  时间:2023-05-08 23:57:23
1  时间:2023-05-08 23:57:23
3  时间:2023-05-08 23:57:23
8  时间:2023-05-08 23:57:23
7  时间:2023-05-08 23:57:23
4  时间:2023-05-08 23:57:23
9  时间:2023-05-08 23:57:23
6  时间:2023-05-08 23:57:23
5  时间:2023-05-08 23:57:23
10  时间:2023-05-08 23:57:23
结束时间:   2023-05-08 23:57:23

多线程方案四:使用xargs -P控制并发数(未成功)

#xargs命令有一个-P参数,表示支持的最大进程数,默认为1。为0时表示尽可能地大,即方案2的效果

#/bin/bash
all_num=10
thread_num=5
echo -e "开始时间:\t$(date +"%Y-%m-%d %H:%M:%S")"
seq 1 ${all_num} | xargs -n 1 -I {} -P ${thread_num} sh -c "sleep 1;echo -e "${num}  时间:$(date +"%Y-%m-%d %H:%M:%S")""
echo -e "结束时间:\t$(date +"%Y-%m-%d %H:%M:%S")"

多线程方案五:使用GNU parallel命令控制并发数

#GNU parallel命令是非常强大的并行计算命令,使用-j参数控制其并发数量。
    语法:同时并发2个
    parallel -j 2 "命令"::: prog1 prog2

安装方式:
    apt install parallel
    yum install parallel

A、脚本内容如下:
#/bin/bash
all_num=10
echo -e "开始时间:\t$(date +"%Y-%m-%d %H:%M:%S")"
parallel -j 2 "sleep 1;echo -e "${num}  时间:$(date +"%Y-%m-%d %H:%M:%S")"" ::: `seq 1 ${all_num}`
#注意这里加sleep只是为了演示并发的效果,其实并发是执行完前面的一组2个任何后立即执行后一组2个任务,并不是slepp1秒后再执行下一组
echo -e "结束时间:\t$(date +"%Y-%m-%d %H:%M:%S")"

B、执行结果如下:
root@C20230507234325:~# ./test.sh 
开始时间:   2023-05-09 00:20:32
时间:2023-05-09 00:20:32 1
时间:2023-05-09 00:20:32 2
时间:2023-05-09 00:20:32 3
时间:2023-05-09 00:20:32 4
时间:2023-05-09 00:20:32 5
时间:2023-05-09 00:20:32 6
时间:2023-05-09 00:20:32 7
时间:2023-05-09 00:20:32 8
时间:2023-05-09 00:20:32 9
时间:2023-05-09 00:20:32 10
结束时间:   2023-05-09 00:20:38

C、脚本内容如下
root@C20230507234325:~# cat host_list.txt 
baidu.com
114.114.114.114
9.9.9.9
211.141.90.68
qq.com
119.84.72.161
119.84.72.132
8.8.8.8
1.1.1.1

D、执行脚本:
方式一:cat host_list.txt | parallel -j 2 ping -c 1 {}
方式二:parallel -j 2 ping -c 1 {} < host_list.txt

案例五:同时下载多个文件

1、准备好下载的url
root@C20230507234325:~# cat host_list.txt 
https://server1.cyberciti.biz/20170406_15.jpg
https://server1.cyberciti.biz/20170406_16.jpg
https://server1.cyberciti.biz/20170406_17.jpg
https://server1.cyberciti.biz/20170406_14.jpg
https://server1.cyberciti.biz/20170406_18.jpg
https://server1.cyberciti.biz/20170406_19.jpg
https://server1.cyberciti.biz/20170406_20.jpg
https://server1.cyberciti.biz/20170406_22.jpg
https://server1.cyberciti.biz/20170406_23.jpg
https://server1.cyberciti.biz/20170406_21.jpg
https://server1.cyberciti.biz/20170420_15.jpg
https://server1.cyberciti.biz/20170406_24.jpg

2、脚本内容如下
#!/bin/bash
# Our custom function
cust_func(){
  wget -q "$1"
}

while IFS= read -r url
do
        cust_func "$url" &
done < host_list.txt

wait
echo "All files are downloaded."
声明:本文为原创,作者为 辣条①号,转载时请保留本声明及附带文章链接:https://boke.wsfnk.com/archives/540.html
谢谢你请我吃辣条谢谢你请我吃辣条

如果文章对你有帮助,欢迎点击上方按钮打赏作者

最后编辑于:2023/5/16作者: 辣条①号

现在在做什么? 接下来打算做什么? 你的目标什么? 期限还有多少? 进度如何? 不负遇见,不谈亏欠!

暂无评论

发表回复

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

arrow grin ! ? cool roll eek evil razz mrgreen smile oops lol mad twisted wink idea cry shock neutral sad ???

文章目录