32.1 不可靠信号问题

  • 发生信号时关联动作被重置为默认设置

    • 信号可能丢失
    • 程序片段
      • 在进入 sig_int 与再次调用 signal 之间发生的 SIGINT 信号将不会捕获
      • 导致进程终止

    

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

 #include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> void sig_handler(int signo)
{
if(signo == SIGINT){
printf("process the SIGINT\n");
sleep();
printf("%d catch SIGINT\n", getpid());
printf("process the SIGINT finished\n");
} if(signo == SIGTSTP){
printf("process the SIGTSTP\n");
sleep();
printf("%d catch SIGTSTP\n", getpid());
printf("process the SIGTSTP finished\n");
}
} int main(void)
{
if(signal(SIGINT, sig_handler) == SIG_ERR){
perror("signal sigint error");
} if(signal(SIGTSTP, sig_handler) == SIG_ERR){
perror("signal sigtstp error");
} printf("begin running\n"); while() pause(); ///< 进程暂停等待信号 printf("end running\n");
return ;
}

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

  • 无法暂时阻塞信号

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

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h> int is_sig_occ = ; void sig_handler(int signo)
{
printf("signo occured: %d\n", signo);
is_sig_occ = ;
} int main(void)
{
if(signal(SIGINT, sig_handler) == SIG_ERR){
perror("signal sigint error");
} printf("begin running\n");
while(is_sig_occ == ){
sleep();
pause(); ///< 进程暂停等待信号发生
}
printf("I will running\n");
return ;
}

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

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

32.2 信号的特点

  • 信号的发生是随机的,但信号在何种条件下发生是可预测的
  • 进程刚开始启动时,所有信号的处理方式要么默认,要么忽略,忽略是 SIGUSR1 和 SIGUSR2 两个信号,其他都采取默认方式(大多数是终止进程)
  • 进程在调用 exec 函数后,原有信号的捕捉函数失效
  • 子进程的诞生总是继承父进程的信号处理方式
  • 在系统层面上,信号的发生是可靠的,
    • 在Linux 中的可靠性只保证依次,进程在处理信号期间若发生同类型的信号不会丢失(内核会保留),会被延迟处理,但同类型信号的多次发生只会保留一次,即被处理一次。
    • 若不同类型的信号发生,也会被内核保留直接会被处理,处理完后,再处理原有信号

三十二、Linux 进程与信号——不可靠信号的更多相关文章

  1. 三十、Linux 进程与信号——信号的概念及 signal 函数

    30.1 信号的基本概念 信号(signal)机制是Linux 系统中最为古老的进程之间的通信机制,解决进程在正常运行过程中被中断的问题,导致进程的处理流程会发生变化 信号是软件中断 信号是异步事件 ...

  2. JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用

    JAVA之旅(三十二)--JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用 GUI写到一半电脑系统挂了,也就算了,最多GUI还有一个提示框和实例, ...

  3. (转载)Android项目实战(三十二):圆角对话框Dialog

    Android项目实战(三十二):圆角对话框Dialog   前言: 项目中多处用到对话框,用系统对话框太难看,就自己写一个自定义对话框. 对话框包括:1.圆角 2.app图标 , 提示文本,关闭对话 ...

  4. Bootstrap <基础三十二>模态框(Modal)插件

    模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. 如果您想要单独引用该插件的功能,那么您需要引用  ...

  5. COJ968 WZJ的数据结构(负三十二)

    WZJ的数据结构(负三十二) 难度级别:D: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有 ...

  6. NeHe OpenGL教程 第三十二课:拾取游戏

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  7. 三十二、Java图形化界面设计——布局管理器之CardLayout(卡片布局)

    摘自 http://blog.csdn.net/liujun13579/article/details/7773945 三十二.Java图形化界面设计--布局管理器之CardLayout(卡片布局) ...

  8. Java进阶(三十二) HttpClient使用详解

    Java进阶(三十二) HttpClient使用详解 Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们 ...

  9. Gradle 1.12用户指南翻译——第三十二章. JDepend 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  10. SQL注入之Sqli-labs系列第三十二关(基于宽字符逃逸注入)

    开始挑战第三十二关(Bypass addslashes) 0x1查看源代码 (1)代码关键点 很明显,代码中利用正则匹配将 [ /,'," ]这些三个符号都过滤掉了 function che ...

随机推荐

  1. centos7系统排错

    系统排错 troubleshooting winPE --光盘或u盘启动盘 产生一个PE系统(类似内存上跑的临时系统) 系统排错 rescue 模式 (挽救模式) 类似windows winPE模式 ...

  2. 讲道理,为什么分布式一定要有Redis?

    考虑到绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 Set Value 和 Get Value 两个操作,对 Redis 整体缺乏一个认知.所以我斗胆以 Redis 为题材,对  ...

  3. Mybatis 批量插入时得到插入的id(mysql)

    前言: 在开发中,我们可能很多的时候可能需要在新增时得到刚才新增的id,后续的逻辑需要用到这个id. 在插入单条记录的情况下,这个是很简单的问题.多条记录时有个坑在里面. 单条记录的代码如下 < ...

  4. win32-api: 让 static 控件中的水平横行,垂直居中。

    CreateWindowEx(....., SS_CENTER | SS_CENTERIMAGE); SS_CENTER  能让文字水平居中. SS_CENTERIMAGE 能让文字垂直居中. htt ...

  5. django基于中间件的IP访问频率控制

    一.中间件的代码 注意:成功时返回的是None,那样才会走视图层,返回httpresponse就直接出去了 import time from django.utils.deprecation impo ...

  6. Can not issue data manipulation statements with executeQuery()错误解决

    转: Can not issue data manipulation statements with executeQuery()错误解决 2012年03月27日 15:47:52 katalya 阅 ...

  7. rewind()函数

    函数名: rewind功 能: 将文件指针重新指向一个流的开头用 法: int rewind(FILE *stream);程序例: #include <stdio.h>#include & ...

  8. appium desktop 1.7 byName不能用,重写

    @Override public WebElement findElementByName(String name){ String string="new UiSelector().tex ...

  9. Game1---游戏设计

    自己玩的一些游戏简单策划 先设计3个类似的游戏场景,第一个场景只进行时间限制,第二个场景道具进行上下移动,第三个场景随机生成敌人: 1.上面的台阶道具应该是随着人物的高度上升逐渐生成,逐渐呈现在玩家的 ...

  10. spring mvc后端校验validator

    springmvc中我们使用hibernate的校验框架validation: pom: <validator.version>5.2.4.Final</validator.vers ...