基本操作,shell中创建管道
1 | mkfifo /tmp/fifo |
或者
1 | mknod /tmp/fifo p |
这样,我们就在tmp目录下,创建了一个名为fifo的管道
阻塞读, 写管道
通过echo和cat,就可以方便的读写管道的内容,但是通过cat和echo读写管道时,是阻塞的。
也就是,cat读,如果当前管道无数据,就会一直卡主,直到有数据出来。
echo写,如何没有其他程序读数据,也会一直卡在,直到有人读数据。
1 | echo 123 > /tmp/fifo |
操作如上,这样的话,操作流程会很不方便, 大部分情况下,我们并不希望同步进行。
所以我们可以用非阻塞的方法来读写
非阻塞写管道
为了实现非阻塞操作,我们需要用到重定向
利用重定向‘>&’可以为一个FD赋值,使其指向一个非null的文件,其实就是打开一个FD
1 | 6>&1 |
一个重定向只在当前命令中有效。通过exec可以使IO重定向在当前shell中长期有效:
1 | # 打开FD6 |
我们可以创建一个描述符来关联管道
1 | exec 6<>/tmp/fifo |
这样就创建了一个文件描述符6,和/tmp/fifo进行了绑定
操作6,就相当于操作/tmp/fifo,并且具有一个新特性,写入不阻塞
可以如下操作
1 | echo 123 >&6 |
shell实现多线程(多进程)
在shell下,我们可以使用 & 符号, 来把程序放到后台去运行。
但是在执行较多任务时,控制不了同时运行的个数。只要放入后台,便不厚受到操控
我们可以使用fifo读阻塞,重定向后写不阻塞的特性,来实现后台数目可控
1 | #!/bin/bash |
我们设定了5条线程,100个任务。
1、我们向fifo非阻塞写入5个换行字符。代表5个空闲线程
2、通过for循环使用read来阻塞读取。前5循环会把字符读完,如果下一次读取,没有任务执行完,read将阻塞
3、当前面的任务执行完毕后,会再非阻塞的向fifo写入字符。代表有空闲。read读取到将继续执行
最终保证同时只有5个任务并行。完成100个任务。