Linux信号的使用

概要

  • 信号时软件中断,一种处理异步事件的方法,每个信号都有一个名字,这些名字都是以SIG开头。
  • 产生信号的条件有很多种:
    1、当用户按下终端按键时,引发终端产生的信号。Ctrl+C等。
    2、 硬件产生信号,除了0、无效内存。
    3、进程被调用了kill函数。
    4、检测到了某个软件条件。比如SIGURG(网络链接传来数据)、SIGPIPE(在管道读进程已经终止)、SIGALRM(设置的定时器超时)。

信号的使用

  • 最简单的接口是singnal,但signal的函数原型太复杂,可以使用下面的typedef,可以更简单一些。第一个参数signo是信号名,是接收到此信号的时候,要调用的函数地址(包括:SIG_IGN :忽略系统动作,SIG_DFL :系统默认动作, ):

    #include <signal.h>
    typedef void Sigfunc(int);
    Sigfunc *  signal(int , Sigfunc *);
    
    //信号处理函数
    static void sig_usr(int);
    int main(void ){
    	if(signal(SIGUSR1,sig_usr) == SIG_ERR){
    		err_sys("can't  catch  err!");
    	}
    	pause();
    }
    

    我们在在终端使用:kill USR1 (pid)
    进程就会接收到SIG_USR1信号。
    signal的缺点:不改变信号的处理方式,就不能确定信号的当前处理方式。而sigaction函数则可以确定一个信号的处理方式,无需改变它。

  • 在早期的时候进程信号可能存在丢失的情况,同时,系统对信号的控制能力也很差,系统通常不具备信号的阻塞能力。后来通过捕捉到信号后,设置信号已经发生的标志位的方式,来进行判断信号是否丢失。

  • 当产生一个信号时,事件可以时硬件异常(除以0)、软件异常(定时器超时)、终端信号、kill函数的发生,内核会在进程中以某种形式设置一个标志。当信号传递过程中,我么称之为信号是未决的。如果有多个信号传给一个进程,PoSIX并没有规定它的顺序。

发送信号相关的函数

  • kill和raise。kill将信号发送给进程和进程组,raise函数允许进程向着自身发送信号。
//调用
raise(signo );
//等同于调用,pid > 0 ,信号给到ID为pid的进程;pid==0,信号给到同组所有进程。
kill(getpid(), signo);
  • alarm和pause,alarm函数可设置一个定时器,产生SIGALRM信号,pause函数会使得进程一直挂起,直到捕捉到一个信号。longjmp无法很好的处理信号间的竞争,可选择select和poll函数。
  • sigaction函数是检查或者修改与指定信号相关的处理动作。sigsetjmp和siglongjmp用于非局部转移,常调用longjmp回到主循环中。
  • sigsuspend:用于解除信号阻塞后,被推迟响应的情况。先恢复被屏蔽字,然后重新进入休眠。
  • abort:使得程序异常的终止。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值