文章目录
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."
如果文章对你有帮助,欢迎点击上方按钮打赏作者
暂无评论