今天在调试程序时,sem_timedwait居然返回了一个Interrupted system call,错误码为EINTR。系统中断这东西我一向只闻其名,不见其"人",不想今天遇上了,脑中一片空白,赶紧上网恶补一下。

  系统中断,要从慢系统调用(slow system call)说起,请参考http://blog.csdn.net/benkaoya/article/details/17262053。慢系统调用就是会阻塞的函数调用,一般是IO调用或有锁的函数。如read,sem_timedwait,这些函数可以会阻塞当前进程一段时间,所以"慢"。在阻塞的这段时间里,进程可能会收到内核的一些信号,这些信号优先级高,需要优先处理的,不能等这些调用完成后才处理信号。于是系统先去处理信号,然后强制这些函数以出错的形式返回,其错误码(errno)就是EINTR。这整个过程就是系统中断。

  程序长时间运行,可能会遇到系统中断,如调试时会触发SIGTRAP,子进程当掉会遇到SIGCHLD...这些信号,有可能是正常的,或者不影响程序的运行。如果捕捉到错误就粗暴地将进程关闭,可能造成不必要的损失。因此,在这些慢调用的地方,需要检测错误是否为EINTR。如:

int wait()
{
struct timespec ts; if ( clock_gettime( CLOCK_REALTIME,&ts ) < )
return -; ts.tv_sec += sec;
ts.tv_nsec += nano_sec; ts.tv_sec += ts.tv_nsec/NSECTOSEC;
ts.tv_nsec = ts.tv_nsec%NSECTOSEC; int ret = sem_timedwait( m_psem,&ts );
if ( EINTR == ret )
ret = wait(); /* 遇到系统中断,再等一次 */ return ret;
}

  这是老的处理方法(signal函数),在新的信号处理函数sigaction中可以指定收到某个信号时是否可以自动恢复函数执行(即在处理完消息后,继续执行原来中断的函数,像什么也没发生一样)。参考http://www.gnu.org/software/libc/manual/html_node/Flags-for-Sigaction.html,设置flag为SA_RESTART,表示继续原来的函数。

Macro: int SA_RESTART

This flag controls what happens when a signal is delivered during certain primitives (such as open, read or write), and the signal handler returns normally. There are two alternatives: the library function can resume, or it can return failure with error code EINTR.

The choice is controlled by the SA_RESTART flag for the particular kind of signal that was delivered. If the flag is set, returning from a handler resumes the library function. If the flag is clear, returning from a handler makes the function fail. See Interrupted Primitives.

  

在http://www.gnu.org/software/libc/manual/html_node/Interrupted-Primitives.html#Interrupted-Primitives中,说明了处理了系统中断的三种处理方法。

  • 自己检测EINTR并手动重新调用自己的代码
  • 使用TEMP_FAILURE_RETRY,在表达式返回EINTR并自动调用表达式,就是第一种方法的封装。
  • sigaction中指定SA_RESTART

  在处理系统中断时,会中断当前代码,去执行信息处理函数,然后继续执行当前代码。这相当于一种异步调用,需要考虑函数是否可重入。比如:

char *p = new char[DEFAULT_LEN];

void sig_handler(int signum)
{
delete []p;
p = NULL;
} void read()
{
if ( NULL == p )
return; if ( wait() < ) /* wait 函数见上面 */
return; read( fd,p,DEFAULT_LEN );
}

在这段代码中,read函数看似安全,因为已经检测了p指针。但是,如果在wait的时候触发了信号,调用了sig_handler,处理完sig_handler后继续执行read函数,会操作空指针。还有一些系统函数也是需要检测可重入的。见http://www.ibm.com/developerworks/cn/linux/l-reent.html#resources

PS:之前一直没接触过系统中断,这次收获不少。学习信号时,一直以为SA_RESTART是各和SA_RESETHAND相对应的。一个重复设置信号的处理函数,一个是只设置一次信号的处理函数,然后设置信号的处理函数为默认。没想到SA_RESTART其实是继续执行中断的函数,默认信号的处理函数是重复设置的。

系统中断与SA_RESTART的更多相关文章

  1. MCS-51系统中断优先级的软扩展

    摘要:鉴于MCS-51系统只提供“二级中断嵌套”,提出扩展51系统中断优先级的纯软件方法.其利用51系统内建的中断允许寄存器IE和中断优先级寄存器IP,通过屏蔽字机制来实现:以C51的形式,给出这种扩 ...

  2. 很多win10系统用户都遇见了开机发现任务管理器中有个系统中断进程占用cpu99%的问题,

    很多win10系统用户都遇见了开机发现任务管理器中有个系统中断进程占用cpu99%的问题,尝试了网上提供的方法都不能得到有效的解决.下面小编就为大家详细的介绍电脑工程师提供的正确的解决姿势. 出现系统 ...

  3. Nucleus 实时操作系统中断(下)

    Nucleus 实时操作系统中断(下) Nucleus RTOS兼容性 由于中断在Nucleus SE中的实现方式与Nucleus rto截然不同,因此不应期望有特定的兼容性.Nucleus RTOS ...

  4. Nucleus 实时操作系统中断(上)

    Nucleus 实时操作系统中断(上) Interrupts in the Nucleus SE RTOS 所有现代微处理器和微控制器都有某种中断设施.这种能力对于提供许多应用程序所需的响应能力是必不 ...

  5. 痞子衡嵌入式:嵌入式Cortex-M系统中断延迟及其测量方法简介

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是Cortex-M系统中断延迟及其测量方法. 在嵌入式领域里,实时性是个经常被我们挂在嘴边的概念,这里的实时性主要强调得是当外界事件发生时 ...

  6. 痞子衡嵌入式:利用GPIO模块来测量i.MXRT1xxx的系统中断延迟时间

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1xxx的系统中断延迟时间. 在 <Cortex-M系统中断延迟及其测量方法简介> 一文里,痞子衡介绍了 Cor ...

  7. epoll_wait会被系统中断唤醒

    今天,当一个程序在epoll_wait阻塞时,用strace跟踪了一下,结果epoll_wait就被EINTR唤醒了,并且返回-1: 所以,当epoll_wait返回-1时,需要判断errno是不是E ...

  8. Linux内核分析-系统中断在内核中的实现

    分析system_call中断处理过程 在MenuOS中添加上周所运用到的系统调用 即在Linuxkernel/menu/test.c文件中,添加代码如下: int Mkdir() { const c ...

  9. IDT系统中断描述表以及绕过Xurtr检测的HOOK姿势

    什么是中断?  指当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的程序和执行过程.即在程序运行过程中,系统出现了一个必须由CPU立即处理的情况,此时,CPU暂时中止程序的执行转而处理这个 ...

随机推荐

  1. AJAX上传文件

    function up_files() { var fileSelect = document.getElementById('file-select'); var files = fileSelec ...

  2. OCP-1Z0-051-题目解析-第28题

    28. Which two statements are true regarding constraints? (Choose two.)  A. A foreign key cannot cont ...

  3. 【精品】Android游戏类源码大集合

    Android自定义效果——随机抽奖 一个模拟抽奖的效果,用户设定若干个选项,添加之后,就可以通过程序,来帮助随机选择其中一项出来.这个类似超市里面那种指针转盘抽奖,run之后是一个动态效果图,初始快 ...

  4. JavaScripts学习日记——BOM

    IE 3.0 和 Netscape Navigator 3.0 提供了一种特性 - BOM(浏览器对象模型),可以对浏览器窗口进行访问和操作.使用 BOM,开发者可以移动窗口.改变状态栏中的文本以及执 ...

  5. iOS会议和组织

    全世界有许多iOS会议和组织,如果你没有机会去参加,知道他们的存在和向他们学习对你也是有益的.事实上,他们中有些提供免费的幻灯片.视频,有用资料等,所以你不能够忽视他们. 有一些会议的主题并不仅仅关于 ...

  6. HTML与CSS入门——第十四章  使用边距、填充、对齐和浮动

    知识点: 1.在元素周围添加边距的方法 2.在元素中添加填充的方法 3.对齐的方法 4.float属性的使用 这里提到了CSS禅意花园,这块有时间可以玩玩~ margin和padding:用于添加元素 ...

  7. AVD启动不了 ANDROID_SDK_HOME is defined but could not find *.ini

    报错提示______________________________________________________________________ Starting emulator for AVD ...

  8. 如何把一个表中的部分字段值插入到另一个表中去 这sql吊

    Insert into  JHAC_TB_CODE(CID,CODE,ADD_TIME,USERID,PRO_CODE,USERNAME)  select f_code.FID,f_code.Fcod ...

  9. 网站发布在另外一个网站下面配置伪静态之后图片样式和JS丢失

    <script src="<%=ResolveClientUrl("~/content/js/jquery-1.7.1.min.js") %>" ...

  10. Solr导入数据库数据

    接Solr-4.10.2与Tomcat整合.1.在solrconfig.xml中添加数据导入节点,solrconfig.xml路径为D:\solr\data\solr\collection1\conf ...