起步
现有 shell 脚本如下。即:脚本中有函数 Task1、Task2、Task3,每个函数执行是会打印 start,即将结束时打印 stop,中间用 sleep
模拟耗时操作。
function Task1() {
printf "[$(date)] task1 start.\n"
sleep 10
printf "[$(date)] task1 stop.\n"
}
function Task2() {
printf "[$(date)] task2 start.\n"
sleep 10
printf "[$(date)] task2 stop.\n"
}
function Task3() {
printf "[$(date)] task3 start.\n"
sleep 10
printf "[$(date)] task3 stop.\n"
}
function Main() {
Task1
Task2
Task3
}
Main
执行脚本(sh paralle.sh
),其运行顺序,以及输出结果显而易见。
[root@localhost shells]# sh paralle.sh
[2019年 10月 20日 星期日 22:42:55 CST] task1 start.
[2019年 10月 20日 星期日 22:43:05 CST] task1 stop.
[2019年 10月 20日 星期日 22:43:05 CST] task2 start.
[2019年 10月 20日 星期日 22:43:15 CST] task2 stop.
[2019年 10月 20日 星期日 22:43:15 CST] task3 start.
[2019年 10月 20日 星期日 22:43:25 CST] task3 stop.
那么问题来了,如果我想要并发执行三个任务,应该如何正确操作呢?
& 与 wait
一般来说,我们知道在执行命令之后加上 &
可以使得任务在后台执行,终端空出来后就可以执行其他任务啦。所以代码修改如下是不是就 OK 了呢?
...
function MainParallel() {
Task1 &
Task2 &
Task3 &
}
MainParallel
通过执行脚本发现,Task1、Task2、Task3 的确在并发执行。但有个问题:任务结束后终端被阻塞了!!!
显然,不能交出终端控制权的脚本不是好脚本。正确的做法是,在一系列 &
操作之后,wait
一下,等待所有子任务结束之后,主进程再退出。代码如下:
...
function MainParallel() {
Task1 &
Task2 &
Task3 &
wait
}
MainParallel
最后
事实上,为保险起见,可以把 wait 放在脚本最后。避免因自己的疏漏,导致脚本执行结果不如预期。
...
MainParallel
wait
还不快抢沙发