zoukankan      html  css  js  c++  java
  • 三十二、Linux 进程与信号——不可靠信号

    32.1 不可靠信号问题

    • 发生信号时关联动作被重置为默认设置
      • 信号可能丢失
      • 程序片段
        • 在进入 sig_int 与再次调用 signal 之间发生的 SIGINT 信号将不会捕获
        • 导致进程终止

        

     以前版本会由这个问题,当前的 Linux 版本是安全的

     1 #include <signal.h>
     2 #include <stdio.h>
     3 #include <stdlib.h>
     4 #include <unistd.h>
     5 
     6 void sig_handler(int signo)
     7 {
     8     if(signo == SIGINT){
     9         printf("process the SIGINT
    ");
    10         sleep(5);
    11         printf("%d catch SIGINT
    ", getpid());
    12         printf("process the SIGINT finished
    ");
    13     }
    14 
    15 
    16     if(signo == SIGTSTP){
    17         printf("process the SIGTSTP
    ");
    18         sleep(5);
    19         printf("%d catch SIGTSTP
    ", getpid());
    20         printf("process the SIGTSTP finished
    ");
    21     }
    22 }
    23 
    24 int main(void)
    25 {
    26     if(signal(SIGINT, sig_handler) == SIG_ERR){
    27         perror("signal sigint error");
    28     }
    29 
    30     if(signal(SIGTSTP, sig_handler) == SIG_ERR){
    31         perror("signal sigtstp error");
    32     }
    33 
    34     printf("begin running
    ");
    35 
    36     while(1) pause(); ///< 进程暂停等待信号
    37 
    38     printf("end running
    ");
    39     return 0;
    40 }

    对于连续发送相同信号,会进行延迟处理,发送查过 2 次以上不会处理。此机制与内核有关。

    • 无法暂时阻塞信号
      • 只能忽略信号
      • 信号可能被丢失
      • 程序片段
        • 检测 sig_int_flag 变量和调用 pause 函数之间有个时间窗口
        • 如果再该时间窗口内发生 SIGINT 信号?

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <unistd.h>
     4 #include <signal.h>
     5 
     6 int is_sig_occ = 0;
     7 
     8 void sig_handler(int signo)
     9 {
    10     printf("signo occured: %d
    ", signo);
    11     is_sig_occ = 1;
    12 }
    13 
    14 
    15 int main(void)
    16 {
    17     if(signal(SIGINT, sig_handler) == SIG_ERR){
    18         perror("signal sigint error");
    19     }
    20 
    21     printf("begin running
    ");
    22     while(is_sig_occ == 0){
    23         sleep(5);
    24         pause(); ///< 进程暂停等待信号发生
    25     }
    26     printf("I will running
    ");
    27     return 0;
    28 }

    5s 之内执行的代码,pause后面的程序不会再执行,必须再发送一个信号后才可以执行。

    建议将依赖于信号而执行的代码放置到信号处理函数中执行,否则这些代码可能不会执行

    32.2 信号的特点

    • 信号的发生是随机的,但信号在何种条件下发生是可预测的
    • 进程刚开始启动时,所有信号的处理方式要么默认,要么忽略,忽略是 SIGUSR1 和 SIGUSR2 两个信号,其他都采取默认方式(大多数是终止进程)
    • 进程在调用 exec 函数后,原有信号的捕捉函数失效
    • 子进程的诞生总是继承父进程的信号处理方式
    • 在系统层面上,信号的发生是可靠的,
      • 在Linux 中的可靠性只保证依次,进程在处理信号期间若发生同类型的信号不会丢失(内核会保留),会被延迟处理,但同类型信号的多次发生只会保留一次,即被处理一次。
      • 若不同类型的信号发生,也会被内核保留直接会被处理,处理完后,再处理原有信号
  • 相关阅读:
    基于SSM框架web搜索功能的实现
    使用APICloud打包webapp
    mac如何运行vue项目
    前端和算法实现:给网站上加上自己的水印(以后用上)
    jQuery常用代码片段
    关于vscode的个人配置
    听说你想用git,安装一下咯
    vue创建项目的一种方法
    用js控制css动画效果@keyframes
    axios的封装和拦截
  • 原文地址:https://www.cnblogs.com/kele-dad/p/10140036.html
Copyright © 2011-2022 走看看