信号是异步的,它会在程序的任何地方发生。由此程序正常的执行路径被打破,去执行信号处理函数。
一般情况下 ,进程正在执行某个系统调用,那么在该系统调用返回前信号是不会被递送的。但慢速系统调用除外,如读写终端、网络、磁盘,以及wait和pause。这些系 统调用都会返回-1,errno置为EINTR当系统调用被中断时,我们可以选择使用循环再次调用,或者设置重新启动该系统调用 (SA_RESTART)。

现在说说对上面话的理解:

我认为函数或进程的运行最终都回归结尾系统调用,(呵呵,非官方,自己理解)

那么 “进程正在执行某个系统调用,那么在该系统调用返回前信号是不会被递送的”,就是说大多数进程在运行期间是阻塞信号的,系统调用完再处理,

但是(以下引用APUE):如果在进程执行一个低速系统而阻塞期间捕捉到一个信号,该系统调用被终端不再继续执行

When a system call is slow and a signal arrives while it was blocked, waiting for something, the call is aborted and returns -EINTR , so that the library function will return -1 and set errno to EINTR . Just before the system call returns, the user program's signal handler is called.

(So, what is "slow"? Mostly those calls that can block forever waiting for external events; read and write to terminal devices, but not read and write to disk devices, wait , pause .)

This means that a system call can return an error while nothing was wrong. Usually one will want to redo the system call. That can be automated by installing the signal handler using a call to sigaction with the SA_RESTART flag set. The effect is that upon an interrupt the system call is aborted, the user program's signal handler is called, and afterwards the system call is restarted from the beginning.

我们可以选择使用循环再次调用,或者设置重新启动该系统调用 (SA_RESTART),

这是是低速系统调用被信号中断的解决办法,1循环2SA——RESTART

好啦,实验代码:

#include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <stdbool.h>
  5 #include <signal.h>
  6 #include <sys/types.h>
  7 #include <errno.h>
  8 #include <string.h>
  9
 10 void int_handler (int signum)
 11 {
 12         printf ("int handler %d/n",signum);
 13 }
 14
 15 int main(int argc, char **argv)
 16 {
 17         char buf[100];
 18         ssize_t ret;
 19         struct sigaction oldact;
 20         struct sigaction act;
 21
 22         act.sa_handler = int_handler;
 23         act.sa_flags=0;
 24         act.sa_flags |= SA_RESTART;
 25         sigemptyset(&act.sa_mask);
 26         if (-1 == sigaction(SIGINT,&act,&oldact))
 27         {
 28                 printf("sigaction failed!/n");
 29                 return -1;
 30         }
 31
 32         bzero(buf,100);
 33
 34         ret = read(STDIN_FILENO,buf,10);
 35         if (ret == -1)
 36         {
 37                 printf ("read error %s/n", strerror(errn    o));

38         }
 39         printf ("read %d bytes, content is %s/n",ret,buf    );
 40         sleep (10);
 41         return 0;
 42 }

这里我们就看第二种解决办法SA—restart

运行看结果:

^Cint handler 2
^Cint handler 2
^Cint handler 2
^Cint handler 2
^Cint handler 2
^Cint handler 2
hgfd
read 5 bytes, content is hgfd

^Cint handler 2
在程序read之前不要输入,ctrl+c这样不会中断read输入后主程序就向下运行啦,这样就不在低速的系统调用即read中啦,所以再次ctrl+c结束;

下面改程序:把程序24行注释掉:结果

^Cint handler 2
read error Interrupted system call
read -1 bytes, content is
程序立即结束啦,

但我们和第一次相比也观察到很奇怪的结果

根据结果 比较,其实是第二次运行是把ctrl+c读入,而第一次就是运行啦信号处理函数,不把ctrl+c作为READ的读入,

linux SA_RESTART的问题相关推荐

  1. linux epoll用法

    epoll 是 linux 特有的 I/O 复用函数.它是把用户关心的文件描述符事件放在内核的一个事件列表中,故而,无须像select和poll一样每次调用都重复传入文件描述符或事件集.但是, epo ...

  2. linux 程序收到sigsegv信号_信号

    当其他方式不起作用时(例如标准输入被冻结),信号是提供低优先级信息和用户与其程序交互的便捷方式.它们允许程序在事件发生时清理或执行操作.有时,程序可以选择忽略受支持的事件.由于处理信号的方式,制作一个 ...

  3. Linux内核中的进程等待与其实现解析

    一.进程等待的概述 进程通过 fork 产生子进程,进程也会死亡,进程退出的时候将会进行内核清理,释放所有进程的资源,资源包括:内存资源,文件资源,信号量资源,共享内存资源,或者引用计数减一,或者彻底 ...

  4. 浅谈Linux中的信号处理机制(三)

    一晃眼,已经到9月底了,都来不及去感慨时间匆匆.最近常常会想明年的今天我将会在那里干着什么样的工作?对未来又是憧憬又是担忧,压力山大.无论如何现在还是踏踏实实的学习吧,能这样安安静静学习的日子也不多了 ...

  5. linux c/c++

    1 string 字符串操作 2 3 4 操作数的都是 ( char * )型,操作数必须是指向字符串的指针("a"),不能是字符('a'),操作时不考虑末尾的'\0'. 5 6 ...

  6. Linux信号 二 信号处理函数注册

    每一个信号都有一个信号处理函数,可以是SIG_IGN, SIG_DFL或者是用户自定义的处理函数.使用用户自定义的处理函数需要注册,注册接口有如下两种. 第一种是signal调用 #include & ...

  7. linux调用信号处理程序后返回,如何在Linux上执行异步信号处理程序?

    Source#1(Andries Brouwer)对于单线程进程是正确的 . 源#2(SCO Unix)对于Linux是错误的,因为Linux不喜欢sigwait中的线程(2) . 关于第一个可用的线 ...

  8. OS / Linux / 系统阻塞在系统调用中时如果收到信号,系统如何处理?

    今天在看<深入 Linux 内核架构>这本书的时候,看到如题的场景. 之前的处理方式是检测系统调用函数的返回值,如果返回值为 -1 并且 errno 是 EINTR ,那么就知道了该系统调 ...

  9. Linux Mutex机制与死锁分析

    在Linux系统上,Mutex机制相比于信号量,实现更加简单和高效,但使用也更加严格 1. 任何时刻只有一个任务可以持有Mutex 2. 谁上锁谁解锁 3. 不允许递归地上锁和解锁 4. 当进程持有一 ...

最新文章

  1. iOS 11开发教程(二十)iOS11应用视图美化按钮之设置按钮的状态
  2. 【1】万魂杀MMORPG研发回顾
  3. gdb来调式多线程(转)
  4. mysql中使用CONCAT 实现拼接
  5. php xmldom扩展,如何使用比根更深入的PHP DOM向XML添加新元素?
  6. 强烈推荐:给去美国的新生说几句(转载),超实用
  7. singft 函数 matlab,(新)信号与系统MATLAB实验全.doc
  8. 软件_搭建rtsp视频推送环境
  9. 城市平乱 (dijkstra模板题)
  10. javascript中Math.round获取小数点位数
  11. DICOM通讯(ACSE->DIMSE->Worklist)
  12. 物联网智能空气环境监测系统解决方案
  13. 电脑版微信提示音mp3_安卓充电提示音修改教程,可以自定义哦~
  14. 需求开发应用部署“一条龙”,平安云如何加速容器场景落地
  15. 致丰巢:品牌管理,才是长久之计
  16. 第六期:如何通过知晓云将数据表导出为 Excel 文件
  17. 网课必备·几款特色各异的pdf软件大全
  18. 什么是H3C的BFD MAD
  19. JVM类加载过程,JDK和JER区别
  20. 匹马抢三关:讯飞翻译机3.0的破障之战

热门文章

  1. CTF 隐写工具Steghide
  2. 我为什么不在乎人工智能 / 王垠
  3. html5 指纹识别,Http指纹识别技术
  4. Spring框架基础
  5. python3 value counts函数_Pandas Series.value_counts()实例介绍
  6. 出色性能服务器,表现出色,浪潮服务器独揽MLPerf榜单18个冠军
  7. bugku——抓住一只苍蝇
  8. DevOps到底是什么意思?看完这篇不要再问我了
  9. Python爬取NGA帖子
  10. 菜鸟的数学建模之路(一):最短路径算法