Linux下信号的概念及相关函数

Linux下信号的概念及相关函数

1.基本概念

  • 信号的共性

    1. 简单
    2. 不能携带大量信息
    3. 满足某个特定条件才发送
  • 信号的特质

    • 信号是软件层面上的中断,一旦信号产生,无论程序执行到什么位置,必须停止运行来处理信号,处理结束后才能执行别的指令
    • 所有信号的产生和处理都是由内核完成的
  • 与信号相关的事件和状态

    • 产生信号

      1. 按键产生,如:Ctrl+c、Ctrl+z、Ctrl+\
      2. 系统调用产生,如:kill、raise、abort
      3. 软件条件产生,如:定时器alarm
      4. 硬件异常产生,如:非法访问内存(段错误)、除0(浮点数除外)、内存对齐出错(总线错误)
      5. 命令产生,如:kill命令
    • 信号的处理方式

      1. 执行默认操作
      2. 忽略(丢弃)
      3. 捕捉(调用户处理函数)
    • 递达与未决

      • 递达:产生并且送达到进程,直接被内核处理掉
      • 未决:产生与递达之间的状态
    • 未决信号集和阻塞信号集

      • 未决信号集:
        1. 信号产生,未决信号集中描述该信号的位立刻翻转位1,表示该信号处于未决状态。当信号被处理时对应位翻转回0,这一时刻往往非常短暂。
        2. 信号产生后由于某些原因(主要为阻塞)不能抵达。这类信号的集合称为未决信号集。屏蔽解除前,信号一直处于未决状态。
      • 阻塞信号集(信号屏蔽字):将某些信号写入集合,对他们设置屏蔽。当屏蔽某信号后,再次收到这个信号,该信号的处理将推后。
      • 两者的本质都是位图。
  • 信号四要素

    1. 编号
    2. 名称
    3. 事件
    4. 默认处理动作

2.常用的信号

  1. SIGHUP(1):当进程退出shell时,由该shell启动的所有进程将收到这个信号,默认动作终止进程

  2. SIGINT(2):当用户按下Ctrl+C组合键的时候,用户终端向正在进行中的由该终端启动的程序发出这个信号,默认动作为终止进程

  3. SIGQUIT(3):当用户按下Ctrl+\组合键的时候产生该信号,用户终端向正在运行中由该终端启动的程序发出的信号,默认动作为终止进程

  4. SIGBUS(7):非法访问内存地址,包括内存对齐出错,默认动作为终止进程并且产生core文件

  5. SIGFPE(8):在发生致命的运算错误时发出。不仅包括浮点运算错误,还包括溢出和除数等于0等所有的算法错误,默认动作为终止进程并且产生core文件

  6. SIGKILL(9):无条件终止进程。本信号不能被忽略、处理和阻塞。默认动作为终止进程。它向系统管理员提供了杀死任何进程的方法。

  7. SIGUSR1(10):用户定义的信号,即程序员可以在程序中定义并使用该信号,默认动作为终止进程

  8. SIGSEGV(11):指示进程进行了无效内存访问。默认动作为终止进程并且产生core文件

  9. SIGUSR2(12):用户定义的信号,即程序员可以在程序中定义并使用该信号,默认动作为终止进程

  10. SIGPIPE(13):Broken pipe向一个没有读端的管道写数据。默认动作为终止进程

  11. SIGALRM(14):定时器超时,超时的时间由系统调用alarm设置,默认为终止进程

  12. SIGTERM(15):程序结束信号,与SIGKILL不同在于该信号可以被阻塞和终止。通常用于指示程序正常退出,执行shell命令kill时,缺省产生这个信号,默认动作为停止进程

  13. SIGCHLD(17):子进程状态发生变化时,父进程会收到这个信号,默认为忽略这个信号

  14. SIGSTOP(19):停止进程的执行,该信号不能被忽略、处理和阻塞,默认动作为暂停进程

3.软件条件产生信号

  1. alarm函数

    • 原型

      unsigned int alarm(unsigned int seconds);
      
    • 作用:定时给自己发SIGALRM信号

    • 返回值:

      0或者剩余的秒数

    • 参数:

      seconds:定时秒数

    • time指令:查看程序的执行时间,实际时间=用户时间+内核时间+等待时间

  2. setitimer函数

    • 原型

      int setitimer(int which, const struct itimerval* new_value,									  struct itimerval* old_value);
      
    • 参数:

      which:指定定时方式

      • 自然定时:ITIMER_REAL→14)SIGALRM

        计算自然时间

      • 虚拟空间计时(用户空间):ITIMER_VIRTUAL→26)SIGVTALRM

        计算进程占用CPU的时间

      • 运行时计时(用户+内核):ITMER_PROF→27)SIGPROF

        计算占用CPU以及执行系统调用的时间

      new_value:定时时间

      • 类型:

        struct itimerval{
        	struct timeval it_interval;  //设定两次定时器的间隔时间
        	struct timeval it_value;     //定时的时长
        }
        struct timeval{
        	time_t   	 tv_sec;   
        	suseconds_t  tv_usec;
        }
        

      old_value:传出参数,上次定时剩余时间

    • 返回值

      成功:0

      失败:-1,设置errno

4.kill函数/命令产生信号

  • kill命令

    kill + - +信号编号 + 进程号

  • kill函数

    • 原型:

      int kill(pid_t pid, int sig);
      
    • 参数:

      pid:

      ​ 1. > 0 发送信号给指定的进程

      ​ 2. = 0 发送给于kill函数进程属于同一个进程组的所有进程

      ​ 3. < -1 取|pid|发送给对应的进程组

      ​ 4. = -1 发送给进程有权限发送的系统中的所有进程

      int:信号编号

    • 返回值:

      成功:0

      失败:-1,设置errno

5.信号集操作函数

sigset_t set;                         	   //自定义信号集
int sigemptyset(sigset_t* set);            //清空信号集
int sigfillset(sigset_t* set);             //将信号集全部置1
int sigaddset(sigset_t* set, int signum);  //将一个信号添加到集合中
int sigdelset(sigset_t* set, int signum);  //将一个信号从集合中删除
//判断一个信号是否在集合里
int sigismember(const sigset_t* set, int signum);
  • 设置信号屏蔽字和解除屏蔽

    • 原型

      int sigprocmask(int how, const sigset_t* set, sigset_t* oldset);
      
    • 参数:

      how:

      • SIG_BLOCK 设置阻塞

      • SIG_UNBLOCK 取消阻塞

      • SIG_SETMASK 用自定义的set替换mask

      set:自定义的set

      oldset:旧的mask,传出参数

  • 查看未决信号集

    • 原型

      int sigpending(sigset_t* set);
      
    • 参数

      set:传出的未决信号集

6.信号捕捉

  • signal函数

    • 原型

      sighandler_t signal(int signum, sighandler_t handler);
      
    • 参数:

      signum:信号的编号

      handle:信号的处理函函数,只能为返回值空参数int的函数

      • typedef void (*sighandler_t)(int);
        
    • 返回值:

      成功:返回旧的处理函数指针

      失败:SIG_ERR,设置errno

  • sigaction函数

    • 原型:

      int sigaction(int signum, const struct sigaction* act, struct 				  sigaction* oldact);
      
    • 参数:

      signum:信号的编号

      sigaction:存放信号动作的结构体

      • struct	sigaction{
            //信号处理函数
            void 	 (*sa_handler)(int);
            void 	 (*sa_sigaction)(int, siginfo_t* ,void*);
            sigset_t sa_mask;      //信号处理函数里维护的屏蔽信号集
            int      sa_flags;	   //设置默认属性
            void     (*sa_restorer)(void);
        }
        
  • 注意事项:

    1. 捕捉函数执行期间,信号屏蔽字由mask→sa_mask,捕捉函数结束后回复为mask
    2. 捕捉函数执行期间,本信号会被自动屏蔽(sa_flag = 0)
    3. 捕捉函数执行期间,被屏蔽信号多次发送,解除屏蔽后只处理一次

7.SIGCHLD信号

  • 信号的产生条件

    1. 子进程终止时
    2. 子进程接收到SIGSTOP信号停止时
    3. 子进程处在停止态,接收到SIGCONT后唤醒时
  • 作用:可以用于回收子进程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值