linux中信号的处理函数,Linux — 信号 信号处理和信号处理函数详解

信号处理

在Linux下当我们想强制结束一个程序的时候,我们通常会给它发送一个信号然后该进程捕捉到信号,再然后该进程执行一定操作最

终被终止.信号是UNIX和Linux系统响应某些条件而产生的一个事件,接收到该信号的进程会相应地采取一些行动。通常信号是由一

个错误产生的。但它们还可以作为进程间通信或修改行为的一种方式,明确地由一个进程发送给另一个进程。一个信号的产生叫生

成,接收到一个信号叫捕获。信号的捕捉这篇可能不会详细的说到,因为我想给它专门讲一个博客,因为信号捕捉的实例也是蛮多

的.

首先我们认识一下这些信号:

$ 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     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

列表中,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信

号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。我们这些新手就着重研究

前31个,后面的对于现在来说用处不大.

信号的产生:

产生信号的条件主要有:

1.用户在终端按下某些建时,终端驱动程序会发送信号给前台进程,例如ctrl -c 产生SIGINT信号.ctrl-\产生SIGQUIT信号,Ctrl-Z产生SIGTSTP信号(可使前台进程停止)

2.硬件异常产生信号,这些条件由硬件检测到并通知内核,然后内核向当前进程发送适当的信号.例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释为SIGFPE信号发送给进程.在比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程.

3,一个进程调用kill(2)函数可以发送信号到另一个进程.可以用kill(1)命令发送信号给某个进程,kill(1)命令也是调用kill(2)函数实现的,如果不明确指定信号则发送SIGTERM信号,该信号的默认处理是终止进程.当内核检测到某种软件条件发生时也可以通过信号通知进程. 例如闹钟超时产生SIGALRM信号,向读端已关闭的管道写数据时产生SIGPIPE信号.如果不想按默认动作处理信号,用户程序可以调用sigacttion(2)函数告诉内核处理某种信号.

再然后,你接收到信号的处理动作有一下三种:

1.忽略此信号

2.执行该信号的默认处理动作

3.提供一个信号处理函数,要求内核处理该信号时切换到用户执行这个处理函数,这种方式称为捕捉一个信号.

信号的阻塞

实际执行信号的处理动作称为信号抵达,信号从产生到抵达之间的状态,称为信号未决.进程可以选择阻塞某个信号。 被阻塞的

号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行抵达的动作. 阻塞和忽略是不相同的,只要信号被阻塞就不会

抵达,而忽略是在抵达之后可选的一种处理动作.

0818b9ca8b590ca3270a3433284dd417.png

每个信号都有两个标志位分别表示阻塞(block) 和 未决(pendin).还有一个函数指针表示处理动作。

信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号抵达才消除该标志.

1.SIGHUP信号未阻塞也未产生过,当它抵达时执行默认处理动作.

2.SIGINT信号产生过,但正在被阻塞,所以暂时不能递达。虽然他的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞.

3.SIGQUIT信号未产生过,一旦产生SIGQUIT信号将被阻塞,它的处理动作是用户自定义函数sighandler。

如果在进程在阻塞某信号时,该信号产生过多次,Liunx这样实现的:常规信号在抵达之前产生多次只计一次,而实时信号在递达之

前产生多可以依次放在一个队列里. 每个信号只有一个bit的未决标志,非0既1,不记录该信号产生了多少次,阻塞标志也是这样表示的. 因此呢,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t为信号集,这个类型可以表示每个信号的"有效"或"无效“状态,在阻塞信号集中"有效"和"无效"的含义是该信号是否被阻塞,而在未决信号集中类似. 阻塞信号集也叫做当前进程的信号屏蔽字. 屏蔽这样理解 "是阻塞 是阻塞 不是忽略"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值