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

输出到几个文件的内容会打印到控制台上
我们可以使用exec 指令自行定义、绑定文件描述符,文件描述符的取值范围是3-(ulimit -n)-1
在我本机这个范围是3-1023

linuxidc@linuxidc:~/linuxidc.com$ ulimit -n
1024
linuxidc@linuxidc:~/linuxidc.com$ exec 1025<>linuxidc
bash: 1025: 错误的文件描述符
linuxidc@linuxidc:~/linuxidc.com$ exec 1022<>linuxidc

下面开始介绍如何使用管道文件和文件描述符来控制进程并发:

mkfifo
exec 5<>linuxidc
rm -f linuxidc

首先创建一个管道文件linuxidc,然后使用exec命令将该文件的输入输出绑定到5号文件描述符,而后删除该管道文件,这里删除的只是该文件的Inode,实际文件已由内核open函数打开,这里删除并不会影响程序执行,当程序执行完后,文件描述符会被系统自动回收。

for ((i=1;i<=10;i++)); do
  echo >&5
done

通过一个for循环向该文件描述符写入10个空行,这个10其实就是我们定义的后台进程数量,这里需要注意的是,管道文件的读取是以行为单位的。

for ((j=1;j<=100;j++)); do
  read -u5
  {
    echo test$j
    sleep 2
    echo >&5
  }&
done

wait

这里假定我后台有100个任务,而我们在后台保证只有10个进程在同时运行
read -u5 的作用是,读取5号文件描述符中的一行,就是读取一个空行
在减少文件描述符的一个空行之后,在后台执行一次任务,而任务在执行完成以后,会向文件描述符中再写入一个空行,这是为什么呢,因为如果我们写入空行的话,当后台放入了10个任务之后,由于没有可读取的空行,read -u5就会被阻塞住!

exec 5>&-
exec 5<&-

我们生成做绑定时 可以用 exec 5<>linuxidc 来实现,但关闭时必须分开来写> 读的绑定,< 标识写的绑定 <> 则标识 对文件描述符5的所有操作等同于对管道文件linuxidc的操作。
完整代码如下:

#!/bin/bash

mkfifo linuxidc
exec 5<>linuxidc
rm -f tm1

for ((i=1;i<=10;i++)); do
  echo >&5
done

for ((j=1;j<=100;j++)); do
  read -u5
  {
    echo test$j
    sleep 2
    echo >&5
  }&
done

wait

exec 5>&-
exec 5<&-

这样,就实现了进程的并发控制。

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

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

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