shell 并发执行多任务

Shell 2019-10-22 1601 字 1133 浏览 点赞

起步

现有 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


本文由 Guan 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论