shell-多进程及绑定
我今天学了些啥?nothing!没精神,好像又到了一轮低迷期。上一次是八月份吧,成天就想着生活的意义是啥。。。。。。
伪多进程
前几天写了个shell多进程,自我感觉良好。觉得不过如此吗?但是今天好好看了一下,实际上是伪多进程,因为在程序运行时用ps查看了一下,根本就没达到预期的进程数。而且从时间上也可以看出,正常跑下来需要三分钟,开了八个进程结果还是需要一份半。
所以分析了一下,是短板效应吧。最慢的进程拉低了总的效率,所以说是伪多进程了。
1 | 大致是这么个结构 |
wait等待所有
这里面wait
的作用是等待所有的后台程序都执行完,才会继续执行下面的语句。从而达到多进程的目的,不至于无法控制进程数。
但是这么写就有个问题,那就是放入后台的执行速度并不同,实际情况是大多数都已经执行完了,但是还有一个两个速度很慢,那么只能继续等待。这就是为什么达不到预期的进程数的原因。
真多进程
我想要达到的效果是:每时每刻都有预期的进程数在后台执行,先执行完的继续执行下一个,只要保证总的进程数一定就行,有一个动态调整过程。
所以就用到了以前觉得没啥作用的管道文件。常常使用的都是匿名管道(|
),不怎么常用的就是管道文件了,我也就拿来做了个terminal交互的功能(用一个terminal给另一个发送指令),没想到还可以用到多进程中。
管道嘛,有了输入,会一直等待输出,直到输出成功为止。有了输出的接收端,就会一直等待输入,直到输入数据为止。正是利用了管道输入输出阻塞的这个特性,避免了使用wait带来的全部等待。先创建进程数那么多的管道,等待输出,每循环一次,接受一个输入,将数据读出,放入后台,在这个执行完后,再生成一个管道输入,管道数为定值,所以循环想要开始就得有管道的输入。
1 | 接受一个进程数 |
这里我搞不懂为什么要把fifo文件删除掉,删除了为什么不影响绑定?
这样运行之后,使用ps查看确实是保持着预期的进程数,而且在开了八个进程后时间由三分多钟缩短为20多秒。so it is true multi process
重定向
1 | /dev/null #标准输出写入/dev/null |
上面的输入,输出重定向,只对当前那条指令是有效的。如果需要在绑定之后,接下来的所有命令都支持的话。就需要用exec命令永久绑定。
exec绑定
1 | exec 文件描述符[n] <或> file或文件描述符或设备 |
1 | 例如:将标准输出绑定到文件 |
利用这个特性,可以做许多很多奇特的事,比如我们在脚本中需要将许多输出写入一个文件,之前不是需要在这么写吗echo "something" >/log/somelogfile
,grep 'someword' somefile >/log/somelogfile
。是不是有点麻烦,现在可以把标准输出重定向到文件中,再也不需要写重定向了,标准输出自动重定向,很神奇。
1 | eg: |