shell控制多个进程并发执行实例

shell中实现多进程实际上就是将多个任务放到后台中执行而已,但是现在需要控制多进程并发的数量该如何实现呢?别急,我们一步一步来实现这个目标,首先从最原始的串行执行开始:

#!/bin/bash
start=`date +%s`

for i in $(seq 1 5); do
  echo linuxidc.com
  sleep 2
done

end=`date +%s`

time=$(($end - $start))
echo "time: $time"

执行结果:

linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.com.sh
linuxidc.com
linuxidc.com
linuxidc.com
linuxidc.com
linuxidc.com
time: 10

shell控制多个进程并发执行实例

这是最原始的一种处理方式,串行执行,无法有效利用计算机的资源,并且效率低下。如果可以一次执行多个任务的,把它放到后台即可,我们做如下改进:

#!/bin/bash
start=`date +%s`

for i in $(seq 1 5); do
  {
  echo linuxidc.com
    sleep 2
  }&
done

wait

end=`date +%s`

time=$(($end - $start))
echo "time: $time"

首先看下执行结果:

linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.com.sh
linuxidc.com
linuxidc.com
linuxidc.com
linuxidc.com
linuxidc.com
time: 2

shell控制多个进程并发执行实例

说下改动,首先我把for循环中的代码用{}包为一个块,然后增加&符号使其后台运行,之后增加wait指令,该指令会等待所有后台进程结束,如果不加wait,程序直接往下走,最终打出的time将会是0。现在程序已经由之前的10秒缩短为2秒,似乎效果不错,不过试想这样一个场景,有1000个这样的任务,如果还是以这种方式执行,机器负载是扛不住的,我们必须想一种办法来控制进程的并发数,那就是管道和文件描述符。

首先介绍下管道(pipe):

无名管道

它经常出现在我们的命令中,例如cat /etc/passwd | awk -F: '{print $1}',其中"|"就是管道,它将前一个命令的结果输出到后一个进程中,作为两个进程的数据通道,不过他是无名的。

有名管道

使用mkfifo命令创建的管道即为有名管道,例如,mkfifo pipefile, pipefile即为有名管道。

管道有一个显著的特点,如果管道里没有数据,那么去取管道数据时,程序会阻塞住,直到管道内进入数据,然后读取才会终止这个操作,反之,管道在执行写入操作时,如果没有读取操作,同样会阻塞,下面是实例:

linuxidc@linuxidc:~/linuxidc.com$ mkfifo linuxmi
linuxidc@linuxidc:~/linuxidc.com$ echo > linuxmi
# 此时会阻塞在这

shell控制多个进程并发执行实例

此时我新开一个窗口再执行读操作

linuxidc@linuxidc:~/linuxidc.com$ cat linuxmi

shell控制多个进程并发执行实例

这时窗口一中的进程才会终止,再来看先读的情况:

linuxidc@linuxidc:~/linuxidc.com$ cat linuxmi
# 同样阻塞停滞在此

shell控制多个进程并发执行实例

新开窗口执行写操作:

linuxidc@linuxidc:~/linuxidc.com$ echo > linuxmi

shell控制多个进程并发执行实例

这时窗口一会立刻读出内容并顺利完成

接下来看一下文件描述符

Linux系统在初始运行时,会自动绑定三个文件描述符0 1 2 对应 stdin ,stdout, stderr,在/proc/self/fd可以找到

linuxidc@linuxidc:~/linuxidc.com$ cd /proc/self/fd
linuxidc@linuxidc:/proc/self/fd$ ll
总用量 0
dr-x------ 2 linuxidc linuxidc  0 4月  26 15:35 ./
dr-xr-xr-x 9 linuxidc linuxidc  0 4月  26 15:35 ../
lrwx------ 1 linuxidc linuxidc 64 4月  26 15:35 0 -> /dev/pts/3
lrwx------ 1 linuxidc linuxidc 64 4月  26 15:35 1 -> /dev/pts/3
lrwx------ 1 linuxidc linuxidc 64 4月  26 15:35 2 -> /dev/pts/3
lrwx------ 1 linuxidc linuxidc 64 4月  26 15:35 255 -> /dev/pts/3

# 绑定到我们的终端设备上

linuxidc@linuxidc:/proc/self/fd$ echo linuxidc.com > /proc/self/fd/1
linuxidc.com
linuxidc@linuxidc:/proc/self/fd$ echo linuxidc.com > /proc/self/fd/2
linuxidc.com

shell控制多个进程并发执行实例

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/5e4f46354f6b6a5d522381bace17ec2a.html