系统中断与SA_RESTART
今天在调试程序时,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,readorwrite), and the signal handler returns normally. There are two alternatives: the library function can resume, or it can return failure with error codeEINTR.The choice is controlled by the
SA_RESTARTflag 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的更多相关文章
- MCS-51系统中断优先级的软扩展
摘要:鉴于MCS-51系统只提供“二级中断嵌套”,提出扩展51系统中断优先级的纯软件方法.其利用51系统内建的中断允许寄存器IE和中断优先级寄存器IP,通过屏蔽字机制来实现:以C51的形式,给出这种扩 ...
- 很多win10系统用户都遇见了开机发现任务管理器中有个系统中断进程占用cpu99%的问题,
很多win10系统用户都遇见了开机发现任务管理器中有个系统中断进程占用cpu99%的问题,尝试了网上提供的方法都不能得到有效的解决.下面小编就为大家详细的介绍电脑工程师提供的正确的解决姿势. 出现系统 ...
- Nucleus 实时操作系统中断(下)
Nucleus 实时操作系统中断(下) Nucleus RTOS兼容性 由于中断在Nucleus SE中的实现方式与Nucleus rto截然不同,因此不应期望有特定的兼容性.Nucleus RTOS ...
- Nucleus 实时操作系统中断(上)
Nucleus 实时操作系统中断(上) Interrupts in the Nucleus SE RTOS 所有现代微处理器和微控制器都有某种中断设施.这种能力对于提供许多应用程序所需的响应能力是必不 ...
- 痞子衡嵌入式:嵌入式Cortex-M系统中断延迟及其测量方法简介
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是Cortex-M系统中断延迟及其测量方法. 在嵌入式领域里,实时性是个经常被我们挂在嘴边的概念,这里的实时性主要强调得是当外界事件发生时 ...
- 痞子衡嵌入式:利用GPIO模块来测量i.MXRT1xxx的系统中断延迟时间
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1xxx的系统中断延迟时间. 在 <Cortex-M系统中断延迟及其测量方法简介> 一文里,痞子衡介绍了 Cor ...
- epoll_wait会被系统中断唤醒
今天,当一个程序在epoll_wait阻塞时,用strace跟踪了一下,结果epoll_wait就被EINTR唤醒了,并且返回-1: 所以,当epoll_wait返回-1时,需要判断errno是不是E ...
- Linux内核分析-系统中断在内核中的实现
分析system_call中断处理过程 在MenuOS中添加上周所运用到的系统调用 即在Linuxkernel/menu/test.c文件中,添加代码如下: int Mkdir() { const c ...
- IDT系统中断描述表以及绕过Xurtr检测的HOOK姿势
什么是中断? 指当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的程序和执行过程.即在程序运行过程中,系统出现了一个必须由CPU立即处理的情况,此时,CPU暂时中止程序的执行转而处理这个 ...
随机推荐
- art.dialog
关闭指定弹出窗: art.dialog({ id: 'hetong' }).close(); 关闭所有的iframe弹出窗,art.dia.close();
- JSF和Struts的区别概述
JSF和Struts的区别概述,都采用taglib来处理表示层:在jsp页面中,二者都是采用一套标记库来处理页面的表示和model层的交互. 据说JSF的主要负责人就是struts的主要作者,所以二者 ...
- correlated subquery and non-correlated subquery
子查询:嵌套在其他查询中的查询称之. 子查询又称内部,而包含子查询的语句称之外部查询(又称主查询). 所有的子查询可以分为两类,即相关子查询和非相关子查询 1>非相关子查询是独立于外部查询的子查 ...
- docker 1.12.3版本搭建私有仓库,上传镜像报错:server gave HTTP response to HTTPS client”
系统环境:centos7 docker版本: 1.12.3(注意版本,可能存在不同版本设置不同的情况) docker registry版本:2.4.1 问题: 成功安装docker registry, ...
- HTML与CSS入门——第十章 创建用于Web上的图像
知识点: 1.选择图像软件的方法 2.准备用于网上的照片的方法 3.创建标题和按钮的方法 4.减少图像中颜色数量的方法 5.创建透明图像的方法 6.创建平铺背景的方法 7.创建Web动画的方法 10. ...
- Android-图标
首先需要申明一点,系统图标并不存在于项目资源中,而是存在于设备中. 这就带来一个大问题,界面风格的控制权交到了不同的设备手中.这是我们不愿意看到的. 如何解决这个问题?有两种方法: 1.创建自己的图标 ...
- Android入门3:从Toolbar到Material Design
在Android5.0(API 21)之后,Toolbar被Google推广,逐渐走入大家视野.具体关于Actionbar和Toolbar的对比就不多啰嗦了,跟着潮流走是没错的.下面先上张简单的效果图 ...
- 0129——UINavigationController
1.创建一个UINavigationController self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].boun ...
- 管理员权限dropfiles和copydata小时失败问题
//处理低权限向高权限进程发消息的失败的问题 if(windows::version::instance()->IsVistaOrLater()) { typedef BOOL (WINAPI ...
- hadoop调优之一:概述
hadoop集群性能低下的常见原因 (一)硬件环境 1.CPU/内存不足,或未充分利用 2.网络原因 3.磁盘原因 (二)map任务原因 1.输入文件中小文件过多,导致多次启动和停止JVM进程.可以设 ...