并发运行
shell脚本一般运行模式就是按照脚本文件逐行运行,如例1:
#!/bin/bash
for i in $(seq 1 6)
do
sleep 1
echo $i
done
echo "end <--"
echo "time consume: ${SECONDS}s"
脚本总耗时6s
加入for循环里面的操作步骤没有前后依赖关系,为了提高效率可以在循环体中添加&将其改成并发运行模式,如例2:
#!/bin/bash
for i in $(seq 1 6)
do
{
sleep 1
echo $i
} &
done
wait #等待for循环结束后再运行后面指令
echo "end <--"
echo "time consume: ${SECONDS}s"
当for循环数量庞大时,为了避免程序占用过多系统内存可以限制并发运行数量(比如最大并行数为3),如例3:
#!/bin/bash
# 创建有名管道
fd_file="/tmp/fd1"
[ -e "${fd_file}" ] && rm -f "${fd_file}"
mkfifo "${fd_file}"
# 创建文件描述符,以可读(<)可写(>)的方式关联管道文件,这时候文件描述符3就有了有名管道文件的所有特性,linux启动后,会默认打开3个文件描述符,分别是:标准输入standard input 0,正确输出standard output 1,错误输出:error output 2,所以这里由3开始
exec 3<> "${fd_file}"
# 关联后的文件描述符拥有管道文件的所有特性,所以这时候管道文件可以删除,我们留下文件描述符来用就可以了
[ -e "${fd_file}" ] && rm -rf "${fd_file}"
#创建令牌
max=3
for i in $(seq 1 ${max})
do
# echo 每次输出一个换行符,也就是一个令牌
echo >&3
done
# read令牌,进行并发操作
for i in $(seq 1 6)
do
# read 命令每次读取一行,也就是拿到一个令牌
read -u3
{
sleep 1
echo $i
# 执行完一个循环体将令牌放回管道
echo >&3
} &
done
wait #等待for循环结束后再运行后面指令
exec 3<&- # 关闭文件描述符的读
exec 3>&- # 关闭文件描述符的写
echo "end <--"
echo "time consume: ${SECONDS}s"
前后台运行
Linux系统进程前后台运行相关的几个命令:&、ctrl+z、jobs、fg、bg
- & 最经常被用到,用在一个命令或代码块的最后(注意需要空格隔开),可以把命令或代码段放到后台执行;
- ctrl + z 可以将一个正在前台执行的命令放到后台,并且暂停;
- jobs 查看当前后台运行的命令列表;
- fg 将后台中的命令调至前台继续运行;
- bg 将一个在后台暂停的命令,变成继续执行(后台运行);
以上面示例1的代码为例进行前后台运行调试结果如下,可以看到后台暂停运行的程序耗时还在继续计算中