tempad
ReadyGo!技术成就梦想 >>Shell教程 >> shell实现Unix进程间信息交换的几种方法

shell实现Unix进程间信息交换的几种方法

ReadyGo!技术成就梦想 网络搜索 efish 2008-2-24 2:50:34
本文将介绍在SCOOpenServer5.0.5系统中使用shell语言来实现进程间信息交换的几种方法:

使用命名管道实现进程间信息交换

使用kill命令和trap语句实现进程间信息交换

使用点命令“.”实现进程间信息交换

使用export语句实现父进程对子进程的信息传递

一、使用命名管道
  命名管道是一种先进先出(FIFO)的数据结构,它允许两个进程通过管道联接实现信息交换。
在Unix系统中,命名管道是一种特殊类型的文件,因此可以对命名管道进行读写操作;当然,同样
也会有读写和执行等权限的限制。

  通过下面的命令可以创建一个命名管道:
  /etc/mknodpipe_namep

  其中“pipe_name”是要创建的命名管道的名字,参数p必须出现在命名管道名字之后。

  命名管道文件被创建后,一些进程就可以不断地将信息写入命名管道文件里,而另一些进程也
可以不断地从命名管道文件中读取信息。对命名管道文件的读写操作是可以同时进行的。下面的例子
显示命名管道的工作过程。

  进程A、B、C中运行的程序只是一条简单的echo命令,它们不断地把信息写入到命名管道文件
/tmp/pipe1中。与此同时,程序中的“readmsg”命令不断地从命名管道文件/tmp/pipe1中读取这些
信息,从而实现这些进程间的信息交换。

  程序执行时,首先创建命名管道文件,此时程序处于等待状态,直到A、B、C进程中某一个进程往
命名管道中写入信息时,程序才继续往下执行。使用rm命令可以删除命名管道文件从而清除已设置的
命名管道。

  下面是一个用于记录考勤的例子:

  在主机上运行的程序/tmp/text产生命名管道/tmp/pipe1,并不断地从命名管道中读取信息送屏幕
上显示。

/tmp/text程序:
if
then
/etc/mknode/tmp/pipe1p
fi
while:
do
readmsg
if
then
continue
else
echo“$msg"
fi
done
  在终端上运行的是雇员签到程序/tmp/text1。每个雇员在任何一台终端上键入自己的名字或代码,
程序/tmp/text1将把这个名字连同当时的签到时间送入命名管道。

/tmp/text1程序:
tty=‘whoamI|awk‘{print$2}’’
while:
do
echo“Enteryourname:\c">/dev/$tty
readname
today=‘date’
echo“$name\t$today"
done>/tmp/pipe1

  当雇员从终端上输入自己的姓名后,运行/tmp/text程序的主机将显示类似下面的结果:

wangThuJan2809:29:26BTJ1999
heThuJan2809:29:26BTJ1999
chengThuJan2809:30:26BTJ1999
zhangThuJan2809:31:26BTJ1999

二、使用kill命令和trap语句
  在Unix系统中,当检测到一个异常的内部状态,或者硬件及外部设备发出请求,或者执行某些指令时,
将会向系统中的进程发出信号报告事件产生。当进程捕获到这些信号后,系统便转去执行预先设定的默认
程序,完成指定的动作;这些预先设定的默认程序称之为信号的系统陷阱。

  在shell中,使用trap语句为信号设置新的陷阱。当shell捕获到一个信号时(信号11除外,因为
shell本身要利用这个信号进行内存分配),它将这个信号传递给所有当前正在执行的程序
(父程序和子程序),并分别执行父程序和子程序中已设置的信号陷阱。一旦陷阱程序执行结束,便返
回中断点,继续执行原来的程序流程。

trap语句的基本格式:
trapcommand_listsignal_list

  command_list:由一个或多个命令(或命令组)构成的命令列表。当命令列表中含有多个命令时要
用单引号或双引号括起来,并且各命令间要用分号隔开。

  signal_list:由一个或多个信号值构成的信号列表,各信号值间要用空格分开。

  在一个shell程序(父程序)中重新设置信号的陷阱并不改变被这个程序所调用的子程序中同名信号
的陷阱。同样,在子程序中设置的信号陷阱也不影响父程序中同名信号的陷阱。

  shell在读取trap语句时,要扫描一次命令列表,以便设置陷阱。在捕获信号后,shell再次扫描命令
列表,执行已设置好的陷阱程序(命令或命令组)。因此,如果命令列表中含有变量置换或命令置换表达
式,shell在第一次扫描命令列表时就会用当前的变量值或命令结果置换这些表达式,使得在捕获到信号而
去执行陷阱程序时,陷阱程序已经不是原来设置的陷阱程序了。为了避免这种情况发生,使用单引号而不是
使用双引号把trap语句中含有变量置换或命令置换表达式的命令列表括起来;因为单引号可以消除所有字符
的特殊含义,这样避免了shell在第一次扫描时执行任何置换或替代操作,直到命令列表被执行时才进行置
换或替代。

  向一个程序或进程传递信号方法很多,比如在程序执行时按下Ctrl+c键或Del键,将向程序传递一个
SIGINT信号,执行该信号的系统陷阱将终止程序执行。使用kill命令传递信号是shell语言编程中最为常用
的方法。

  kill命令的基本格式是:
  killPID

  通常kill命令用来终止一个进程。但如果使用了带有短划线“-”的信号作为参数时,kill命令就发送
该信号给PID指示的一个或多个进程,而不是终止进程。当trap语句捕获到这个信号后便执行设定的信号陷阱
程序,实现进程间的相互通讯。

  下面的例子显示了程序master和slave1、slave2间如何利用信号机制实现相互通讯的。首先在后台运行
程序slave1和slave2,然后运行程序master。在文件/tmp/pro_list中记录了这三个程序的进程号。

  程序slave1首先设置信号15的陷阱,然后把自己的当前进程写入文件/tmp/pro_list;在获得master进程
号后,进入循环状态。当接收到master发出的信号15时,执行陷阱程序,显示相关信息后,向master发出信
号15。

  程序slave2执行情况与slave1相似。

  程序master也是首先设置信号15的陷阱,然后把自己的当前进程写入文件/tmp/pro_list。在取得所有
slave程序进程号后,向这些slave程序发出信号15,然后进入循环等待。当接收到slave1或slave2发出的信
号15时,执行陷阱程序,显示相关信息,杀死所有slave进程,清空文件/tmp/pro_list,然后退出。

程序/tmp/slave1:
slave(){
echo“slave1hasreceivedsighalfrommaster"
echo“Requestmastertokillslave1process"
kill-15$master_pid
}
trapslave15
echo“slave1_pid$$">>/tmp/pro_list
sleep1
while:
do
master_pid=‘awk’$1~/master/
{print$2}‘/tmp/pro_list’
if
thenbreak
fi
done
while:
do
sleep1
done

程序/tmp/slave2:
slave(){
echo“slave2hasreceivedsighalfrommaster"
echo“Req

   

[1]  [2]  [3]  上一页  下一页
责任编辑: efish 参与评论 查找更多:
相关文章
Shell递归程序设计-批量转换大写文件名为小写 Shell递归程序设计-批量转换大写文件名为小写
shell编程例子--一个简单的目录菜单 shell编程例子--一个简单的目录菜单
shell编程例子--一个.login例子 shell编程例子--一个.login例子
Bash中的变量 Bash中的变量
Bash中对变量的操作 Bash中对变量的操作
Bash中的特殊字符 Bash中的特殊字符
赶走一些你不希望进入的用户 赶走一些你不希望进入的用户
也谈在Unix系统中杀死相关终端的进程 也谈在Unix系统中杀死相关终端的进程
从ifconfig中得到IP地址 从ifconfig中得到IP地址
FREEBSD下使用crunch集成编译程序 FREEBSD下使用crunch集成编译程序
2秒记住本站域名

玩过泡泡龙吗?Readygo?Go! 再加上.Com.Cn的后缀,那就是大名小顶的ReadyGo.com.cn

分类导航
ReadyGo!技术成就梦想