科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Shell实现Unix进程间信息交换的几种方法

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

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

命名管道是一种先进先出(FIFO)的数据结构,它允许两个进程通过管道联接实现信息交换......

作者:蓝色键盘 来源:天极论坛 2007年10月28日

关键字: Linux

  • 评论
  • 分享微博
  • 分享邮件
 二、使用kill命令和trap语句

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

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

  trap语句的基本格式:

  trap command_list signal_list

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

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

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

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

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

  kill命令的基本格式是:
  kill [ - signal ] PID

  通常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发出的信 br> 号15时,执行陷阱程序,显示相关信息,杀死所有slave进程,清空文件/tmp/pro_list,然后退出。

程序/tmp/slave1:
slave() {
echo “slave1 has received sighal from master"
echo “Request master to kill slave1 process"
kill -15 $master_pid
}
trap slave 15
echo “slave1_pid $$" >> /tmp/pro_list
sleep 1
while :
do
master_pid=‘awk ’$1 ~/master/
{print $2}‘/tmp/pro_list’
if [ “$master_pid" != “" ]
then break
fi
done
while :
do
sleep 1
done

程序/tmp/slave2:
slave() {
echo “slave2 has received sighal from master"
echo “Request master to kill slave2 process"
kill -15 $master_pid
}
trap slave 15
echo “slave2_pid $$" >> /tmp/pro_list
sleep 1
while :
do
master_pid=‘awk ’$1 ~/master/
{print $2}‘/tmp/pro_list’
if [ “$master_pid" != “" ]
then break
fi
done
while :
do
sleep 1
done

程序/tmp/master:
kill_slave() {
echo “Master has received signals
from slave processes"
echo “End all slave processes"
kill -9 $slave_list
>/tmp/pro_list
exit 0
}
trap kill_slave 15
echo “master_pid $$" >> /tmp/pro_list
sleep 1
slave_list=‘awk ’$1 ~/slave/
{print $2}‘/tmp/pro_list’
echo “Current slave processes are:"
echo “$slave_list"
kill -15 $slave_list
while :
do
sleep 1
done

执行程序:
$ cd /tmp
$ ./slave1&
15638
$ ./slave2&
16831
$ ./master
Current slave processes are:
15638
16831
slave1 has received signal 15 from master
Request master to kill slave1 process
slave2 has received signal 15 from master
Request master to kill slave2 process
Master has received signals from slave processes
End all slave processes
15638 Killed
16831 Killed

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章