shell多线程之进程间通信
Posted Mars.wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell多线程之进程间通信相关的知识,希望对你有一定的参考价值。
工作中往往遇到这种情况,有许多任务,依次执行比较浪费时间,由于任务之间有依赖关系,简单的并发执行又不行。
就如同下面这种情况,任务new和dvidUser是可以并发执行的,fact任务依赖于new任务,fact执行完之后last和stat才能执行;
dvidUser执行完之后dvid和User两个任务才能执行。
针对这种情况,我考虑了操作系统中的信号量机制,通过借助linux中的文件描述符(以下称pipe)来实现这几个任务的并发。
当new执行完之后,向pipe-7中写入自己当前执行的ID(在程序中用$i标识,递增的),然后ID自增,继续执行;
与此同时,fact任务不断从pipe-7中读取,我们称之为$j,然后和自己的任务ID进行比较,会有几种情况:
1.没有读到$j,说明相同ID的前置new任务尚未执行,则fact阻塞;
2.读到$j,$j>ID,fact执行,fact执行完之后将自己的ID同时写入pipe-8和pipe-9),以通知它的后置任务last和stat.
其他的逻辑基本相同。代码如下:
init_pipe.sh
# 初始化file descriptor init_pipe(){ [ -e /tmp/fd1001 ] || mkfifo /tmp/fd1001 exec 1001<>/tmp/fd1001 rm -rf /tmp/fd1001 [ -e /tmp/fd1002 ] || mkfifo /tmp/fd1002 exec 1002<>/tmp/fd1002 rm -rf /tmp/fd1002 [ -e /tmp/fd1003 ] || mkfifo /tmp/fd1003 exec 1003<>/tmp/fd1003 rm -rf /tmp/fd1003 [ -e /tmp/fd1004 ] || mkfifo /tmp/fd1004 exec 1004<>/tmp/fd1004 rm -rf /tmp/fd1004 [ -e /tmp/fd1005 ] || mkfifo /tmp/fd1005 exec 1005<>/tmp/fd1005 rm -rf /tmp/fd1005 [ -e /tmp/fd1006 ] || mkfifo /tmp/fd1006 exec 1006<>/tmp/fd1006 rm -rf /tmp/fd1006 } destroy_pipe(){ exec 1001<&- exec 1001>&- exec 1002<&- exec 1002>&- exec 1003<&- exec 1003>&- exec 1004<&- exec 1004>&- exec 1005>&- exec 1005<&- exec 1006<&- exec 1006>&- }
work.sh
# 初始化file descriptor #source init_pipe.sh source执行脚本,两个脚本在同一个进程中,执行脚本中的环境变量都可以带到主脚本。 # ‘.’=fork,开启一个新的子shell,子shell执行完之后返回父shell,不能带回自己的环境变量; . init_pipe.sh newFun(){ for((i=0;i<10;i++)) do echo \'new\'$i sleep 1 echo $i >& 1001 done } factFun(){ for((i=0;i<10;i++)) do read -u 1001 j if [ $i -le $j ];then echo \'fact\'$i echo $i>& 1002 echo $i>& 1003 echo $i>& 1004 fi sleep 1 done } lastFun(){ for((i=0;i<10;i++)) do read -u 1002 j if [ $i -le $j ];then echo \'last\'$i fi sleep 1 done } statFun(){ for((i=0;i<10;i++)) do read -u 1003 j if [ $i -le $j ];then echo \'stat\'$i fi sleep 1 done } retainFun(){ for((i=0;i<10;i++)) do read -u 1004 j if [ $i -le $j ];then echo \'retain\'$i fi sleep 1 done } dvidUserIdFun(){ for((i=0;i<10;i++)) do echo \'dvidUserId\'$i echo $i>& 1005 echo $i>& 1006 sleep 1 done } dvidFun(){ for((i=0;i<10;i++)) do read -u 1005 j if [ $i -le $j ];then echo \'dvid\'$i fi sleep 1 done } userIdFun(){ for((i=0;i<10;i++)) do read -u 1006 j if [ $i -le $j ];then echo \'userId\'$i fi sleep 1 done } ################################################### init_pipe start_time=`date +%s` newFun & factFun & lastFun & statFun & retainFun & dvidUserIdFun & dvidFun & userIdFun & wait end_time=`date +%s` echo "TIME:[[ $end_time - $start_time]]" destroy_pipe
以上是关于shell多线程之进程间通信的主要内容,如果未能解决你的问题,请参考以下文章