什么是信号

软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。在软件层次上是对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是进程间通信机制中唯一的异步通信机制,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。信号机制除了基本通知功能外,还可以传递附加信息。

收到信号的进程对各种信号有不同的处理方法。处理方法可以分为三类:

Ø  类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处理。

Ø  忽略某个信号(SIG_IGN),对该信号不做任何处理,就象未发生过一样。

Ø  对该信号的处理保留系统的默认值(SIG_DFL),这种缺省操作,对大部分的信号的缺省操作是使得进程终止。进程通过系统调用signal来指定进程对某个信号的处理行为。

查看目前支持的信号值

[root@bogon demo]# kill -l

1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP

6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1

11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM

16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP

21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ

26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR

31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3

38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8

43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13

48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12

53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7

58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2

63) SIGRTMAX-1  64) SIGRTMAX

信号的分类

可以从两个不同的分类角度对信号进行分类:

Ø  可靠性方面:可靠信号与不可靠信号;

Ø  与时间的关系上:实时信号与非实时信号。

可靠信号与不可靠信号

Linux信号机制基本上是从Unix系统中继承过来的。早期Unix系统中的信号机制比较简单和原始,信号值小于SIGRTMIN的信号都是不可靠信号。这就是"不可靠信号"的来源。它的主要问题是信号可能丢失。

随着时间的发展,实践证明了有必要对信号的原始机制加以改进和扩充。由于原来定义的信号已有许多应用,不好再做改动,最终只好又新增加了一些信号,并在一开始就把它们定义为可靠信号,这些信号支持排队,不会丢失。

信号值位于SIGRTMIN和SIGRTMAX之间的信号都是可靠信号,可靠信号克服了信号可能丢失的问题。Linux在支持新版本的信号安装函数sigation()以及信号发送函数sigqueue()的同时,仍然支持早期的signal()信号安装函数,支持信号发送函数kill()。

信号的可靠与不可靠只与信号值有关,与信号的发送及安装函数无关。目前linux中的signal()是通过sigation()函数实现的,因此,即使通过signal()安装的信号,在信号处理函数的结尾也不必再调用一次信号安装函数。同时,由signal()安装的实时信号支持排队,同样不会丢失。

对于目前linux的两个信号安装函数:signal()及sigaction()来说,它们都不能把SIGRTMIN以前的信号变成可靠信号(都不支持排队,仍有可能丢失,仍然是不可靠信号),而且对SIGRTMIN以后的信号都支持排队。这两个函数的最大区别在于,经过sigaction安装的信号都能传递信息给信号处理函数,而经过signal安装的信号不能向信号处理函数传递信息。对于信号发送函数来说也是一样的。

实时信号与非实时信号

早期Unix系统只定义了32种信号,前32种信号已经有了预定义值,每个信号有了确定的用途及含义,并且每种信号都有各自的缺省动作。如按键盘的CTRL ^C时,会产生SIGINT信号,对该信号的默认反应就是进程终止。后32个信号表示实时信号,等同于前面阐述的可靠信号。这保证了发送的多个实时信号都被接收。

非实时信号都不支持排队,都是不可靠信号;实时信号都支持排队,都是可靠信号。

信号相关函数说明

#include <signal.h>

void (*signal(int signum, void (*handler))(int)))(int);

如果该函数原型不容易理解的话,可以参考下面的分解方式来理解:

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler));

第一个参数指定信号的值,第二个参数指定针对前面信号值的处理,可以忽略该信号(参数设为SIG_IGN);可以采用系统默认方式处理信号(参数设为SIG_DFL);也可以自己实现处理方式(参数指定一个函数地址)。

如果signal()调用成功,返回最后一次为安装信号signum而调用signal()时的handler值;失败则返回SIG_ERR。

传递给信号处理例程的整数参数是信号值,这样可以使得一个信号处理例程处理多个信号。

信号案例说明

案例设计

Ø  进程收到SIGHUP,SIGINT,SIGQUIT,提示收到对应的信号,不做任何处理

Ø  进程中有个计数器,当用户发出SIGUSR1,SIGUSR2时,打印出这个计数器的值

Ø  对信号9(SIGKILL)和信号11(SIGSEGV)分别做忽略和默认处理

代码说明:

  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <fcntl.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <limits.h>
  8. #include <string.h>
  9. #include <signal.h>
  10.  
  11. int count = ;
  12. void deal_sig(int signum)
  13. {
  14. switch(signum)
  15. {
  16. case : // SIGHUP
  17. printf("signal SIGHUP cached\n");
  18. break;
  19. case : // SIGINT
  20. printf("signal SIGINT cached\n");
  21. break;
  22. case : // SIGQUIT
  23. printf("signal SIGQUIT cached\n");
  24. break;
  25. case : // SIGUSR1
  26. printf("signal SIGUSR1 cached, count = %d\n", count);
  27. break;
  28. case : // SIGUSR2
  29. printf("signal SIGUSR2 cached, count = %d\n", count);
  30. break;
  31. }
  32. return;
  33. }
  34.  
  35. int main(int argc, char** argv)
  36. {
  37. signal(SIGHUP, deal_sig);
  38. signal(SIGINT, deal_sig);
  39. signal(SIGQUIT, deal_sig);
  40. signal(SIGUSR1, deal_sig);
  41. signal(SIGUSR2, deal_sig);
  42. signal(SIGKILL, SIG_IGN);
  43. signal(SIGSEGV, SIG_DFL);
  44. while()
  45. {
  46. count++;
  47. sleep();
  48. }
  49. return ;
  50. }

结果说明:

tty1:

[root@bogon ipc]# g++ -g -o ipc_signal ipc_signal.cpp

[root@bogon ipc]# ./ipc_signal

^Csignal SIGINT cached          // 这里按下 CTRL + C

signal SIGHUP cached

signal SIGINT cached

signal SIGQUIT cached

signal SIGUSR1 cached, count = 73

signal SIGUSR2 cached, count = 79

Killed                        // 这里发现SIGKILL信号是忽略不掉的,进程还是退出了

[root@bogon ipc]# ./ipc_signal

Segmentation fault (core dumped) // 收到段错误信号,产生core并退出

tty2:

[root@bogon ipc]# ps axu|grep ipc_signal

root      20380  0.0  0.0  11740   828 pts/1    S+   00:50   0:00 ./ipc_signal

root      20389  0.0  0.0 103252   812 pts/2    S+   00:50   0:00 grep ipc_signal

[root@bogon ipc]# kill -HUP 20380

[root@bogon ipc]# kill -INT 20380

[root@bogon ipc]# kill -QUIT 20380

[root@bogon ipc]# kill -USR1 20380

[root@bogon ipc]# kill -USR2 20380

[root@bogon ipc]# kill -KILL 20380

[root@bogon ipc]# ps axu|grep ipc_signal

root      20445  0.0  0.0  11736   780 pts/1    S+   00:52   0:00 ./ipc_signal

root      20448  0.0  0.0 103252   812 pts/2    S+   00:53   0:00 grep ipc_signal

[root@bogon ipc]# kill -SEGV 20445

Linux进程间通信(三) - 信号的更多相关文章

  1. [转]Linux进程间通信——使用信号

    转载于:http://blog.csdn.net/ljianhui/article/details/10128731         经典!!! Linux进程间通信——使用信号 一.什么是信号 用过 ...

  2. Linux进程间通信——使用信号

    一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...

  3. 练习--LINUX进程间通信之信号SIGNAL

    同样的,信号也不要太迷信可靠信号及不及靠信号,实时或非实时信号. 但必须要了解这些信号之间的差异,函数升级及参数,才能熟练运用. ~~~~~~~~~~~~~~~~ 信号本质 信号是在软件层次上对中断机 ...

  4. Linux进程间通信方式--信号,管道,消息队列,信号量,共享内存

    1.概述 通信方法 无法介于内核态与用户态的原因 管道(不包括命名管道) 局限于父子进程间的通信. 消息队列 在硬.软中断中无法无阻塞地接收数据. 信号量 无法介于内核态和用户态使用. 内存共享 需要 ...

  5. linux进程间通信之信号

    1.wait()函数 原型:pid_t  wait(int *status) 子进程退出时,它向父进程发送一个SIGCHLD信号,默认情况是总是忽略SIGCHLD信号,此时进程状态一直保留在内存中,因 ...

  6. Linux进程间通信——使用信号量

    这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信——使用信号.下面 ...

  7. Linux进程间通信--使用信号量【转】

    本文转载自:http://blog.csdn.net/ljianhui/article/details/10243617 这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号 ...

  8. Linux进程间通信——使用信号量(转)

    这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信——使用信号.下面 ...

  9. Linux进程间通信——使用信号量【转】

    本文转载自:http://blog.csdn.net/ljianhui/article/details/10243617 这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号 ...

随机推荐

  1. Matlab绘图时横坐标重叠怎么办

    如横坐标重叠了,咋回事?蛋疼. 后来发现plot里已经横坐标1到50了,我又写了个 set(gca,'XTick',1:1:50);没写XTickLabel,后来我把XTick注视了就好了.

  2. INNO SETUP脚本向导创建的基本脚本

    脚本范例分析:先来看看一段用INNO SETUP脚本向导创建的基本脚本的[Setup]段: [Setup]   AppName=Premiere 6.5 汉化补丁-----------------(程 ...

  3. threadlocal彻底理解

    如果你定义了一个单实例的java bean,它有若干属性,但是有一个属性不是线程安全的,比如说HashMap.并且碰巧你并不需要在不同的线程中共享这个属性,也就是说这个属性不存在跨线程的意义.那么你不 ...

  4. JAVA中使用freemark生成自定义文件(json、excel、yaml、txt)

    原文:http://blog.csdn.net/jinzhencs/article/details/51461776 场景:在我们工作中,有时需要生成一些文件,可能它不是一种标准的格式,比如JSON. ...

  5. Console-算法:fun1(do while)

    ylbtech-Arithmetic:Console-算法[do while]-XX   1.A,Demo(案例) 1.B,Solution(解决方案) using System; namespace ...

  6. Window mode

    D3D window mode:Upper left (0,0)是左上角 OGL window mode:Lower left(0,0)是左下角 nvn API nvn::Device::SetWin ...

  7. as well as

    一.as well 用法: 1.as well常用作状语,作“又:也”解,相当于too或also,常位于句末,无须用逗号与句子分开.如: I am going to London and my sis ...

  8. 关于http和https淘宝支付宝跨域解决方法研究

    关于http和http跨域淘宝解决方式研究: http://buyer.trade.taobao.com/trade/pay.htm?spm=a1z01.2.3.4.0.wZAGp9&bizO ...

  9. 为windows开启winrm service, 以便进行远程管理

    为windows开启winrm service, 以便进行远程管理   是windows 一种方便远程管理的服务:开启winrm service,便于在日常工作中,远程管理服务器,或通过脚本,同时管理 ...

  10. ubuntu12.04 下安装nodejs

    liunx里面安装nodejs我也找了非常多文章,貌似对非常多liunx新手来讲不是非常清楚,以下是我结合一些文章,亲自实践得到的安装步骤.同一时候还有大家关心的与seajs紧密相关的spm模块的安装 ...