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 中的可靠性只保证依次,进程在处理信号期间若发生同类型的信号不会丢失(内核会保留),会被延迟处理,但同类型信号的多次发生只会保留一次,即被处理一次。
      • 若不同类型的信号发生,也会被内核保留直接会被处理,处理完后,再处理原有信号
  • 相关阅读:
    Struts 2 Learning
    C/C++ Learning
    Flipping Bits in Memory Without Accessing Them: An Experimental Study of DRAM Disturbance Errors
    Circular Queue Implementation Principle
    Linux Process Management && Process Scheduling Principle
    duxcms SQL Injection In /admin/module/loginMod.class.php
    oracle:批量插入不同方案对比
    oracle批量插入优化方案
    oracle数据库出现“批处理中出现错误: ORA-00001: 违反唯一约束条件”解决方法
    hive:导出数据记录中null被替换为 的解决方案
  • 原文地址:https://www.cnblogs.com/kele-dad/p/10140036.html
Copyright © 2011-2022 走看看