关于EINTR错误的理解【转】
转自:http://www.xuebuyuan.com/1470645.html
最近在工作中遇到了EINTR错误,感到比较困惑,几番研究之后,颇有心得和收获,特记录如下,便于以后查询,也给有同样困惑的朋友们提供一点借鉴。
我们经常在网络编程中会看到这样,当执行一个可能会阻塞的系统调用后,在返回的时候需要检查下错误码(if errno == EINTR),如果是这样的错误,那我们一般会重新执行该系统调用。所以经常的写法是:
repeat:
if(read(fd, buff, size) < 0)
{
if(errno == EINTR)
goto repeat;
else
printf("read failed");
}
但一般我们在读/写磁盘文件的时候却不太会判断这个错误,那我们到底什么时候该判断而什么时候又不要去判断呢?这是个问题。针对这个问题我特意做了一些测试。首先是读磁盘文件,测试代码如下:
#define _GNU_SOURCE #include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <errno.h> #include <sys/types.h>
#include <sys/stat.h> void hup_handler(int sig)
{
printf(".");
fflush(stdout);
} int main()
{
int i = 0;
struct sigaction act;
const int buffSize = 1 << 27;
int allocated = 0;
char* buf = NULL; act.sa_handler = hup_handler;
act.sa_flags = SA_INTERRUPT;
sigemptyset(&act.sa_mask);
allocated = posix_memalign((void**)&buf, getpagesize(), buffSize);
if (0 != allocated)
{
perror("posix_memalign error");
exit(1);
} sigaction(SIGHUP, &act, NULL);
int fd = open("testfile", O_RDWR | O_DIRECT);
//for (i = 0; i < 1; ++i)
for (;
{
if (lseek(fd, 0, SEEK_SET) == -1)
{
printf("lseek failed: %s\n", strerror(errno));
}
if (read(fd, buf, buffSize) != buffSize)
{
printf("read failed: %s\n", strerror(errno));
}
}
}
代码中注册了信号SIG_HUP的信号处理函数,收到信号的时候应该会进入该处理函数。使用了O_DIRECT方式直接从磁盘读,然后运行该程序。在另外一个终端发送信号
while true; do pkill -HUP read; done
观察read进程,发现read确实进入了信号处理函数(终端输出了"......")但是,程序并没有打印出“read failed”错误,这与我们的预期不太符合,测试发现调用write接口时,现象也一样。
为了进一步验证,我尝试去read终端设备,然后发信号,整个流程跟上面read测试基本相同,测试代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdbool.h> void int_handler(int signum)
{
printf("....\n");
} int main()
{
char buf[128];
ssize_t ret;
struct sigaction oldact;
struct sigaction act; act.sa_handler = int_handler;
//act.sa_flags = SA_INTERRUPT;
act.sa_flags = SA_RESTART;
sigemptyset(&act.sa_mask); if(-1 == sigaction(SIGHUP, &act, &oldact))
{
exit(1);
} bzero(buf, 100); while(true)
{
ret = read(STDIN_FILENO, buf, 10);
if(-1 == ret)
{
perror("read terminal");
//printf("read error%s\n"), strerror(errno);
}
} return 0;
}
编译运行该函数,然后在另外一个终端为其发送信号:
while true; do pkill -HUP read; done
关于EINTR错误的理解【转】的更多相关文章
- EINTR错误
慢系统调用(slow system call):此术语适用于那些可能永远阻塞的系统调用.永远阻塞的系统调用是指调用有可能永远无法返回,多数网络支持函数都属于这一类.如:若没有客户连接到服务器上,那么服 ...
- 关于 promise 吃到错误的理解
关于 promise 吃到错误的理解 下面的内容需要对浏览器原生支持的 promise 的基本用法有了解,如果你还不知道 promise 和 promise 的 catch 方法,你可能需要先在 这里 ...
- 错误的理解引起的bug async await 执行顺序
今天有幸好碰到一个bug,让我知道了之前我对await async 的理解有点偏差. 错误的理解 之前我一直以为 await 后面的表达式,如果是直接返回一个具体的值就不会等待,而是继续执行asyn ...
- linux中对EINTR错误的处理
https://www.cnblogs.com/flyfish10000/articles/2576885.html EINTR错误的产生:当阻塞于某个慢系统调用的一个进程捕获某个信号且相应信号处理函 ...
- Java中的static(1)【持续更新】——关于Eclipse的No enclosing instance of type ... 错误的理解和改正
No enclosing instance of type SomeClass is accessible. Must qualify the allocation with an enclosing ...
- 对express中引入文件时提示Error: Cannot find module错误的理解
打算写个小demo,在引入一个routes文件时,一直提示Error: Cannot find module('./routes')的错误,经过一番了解. 如果要把整个文件夹下所有的模块都引进来 v ...
- OpenStack学习系列-----第二篇 由一个错误看理解整个架构的重要性
看了openstack没几天,然后就开始试着用Java调用所有的API,第一步得到Credentials的时候成功了,然后第二步,传参数使所有的server信息都列出来的时候报错404.具体描述如下( ...
- 简单回射程序之处理accept返回EINTR错误的服务器程序版本
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <errno.h> ...
- DDD学习笔录——领域驱动设计的常见误区(即错误的理解)
可以将DDD看成一种开发思想体系:它促成了一种新的以领域为中心的思维方式. 它是一种学习过程,而非最终目标,这就是DDD的最大优势. 任何团队都可以编写一个软件来满足一组用例的需求,但那些将时间和精力 ...
随机推荐
- python 基础篇 10 函数进阶
本节主要内容:1. 函数参数--动态传参2. 名称空间, 局部名称空间, 全局名称空间, 作⽤域, 加载顺序.3. 函数的嵌套4. gloabal, nonlocal关键字 ⼀. 函数参数--动态传参 ...
- Leetcode 55. Jump Game & 45. Jump Game II
55. Jump Game Description Given an array of non-negative integers, you are initially positioned at t ...
- 基于语音转录的ted演讲推荐
论文地址:https://arxiv.org/abs/1809.05350v1 二. 实现 我们从Kaggle[6]中获取了TED演讲数据集,其中包括2400个TED演讲的数据,包括标题.演讲者.标 ...
- UVA 1085 House of Cards(对抗搜索)
Description Axel and Birgit like to play a card game in which they build a house of cards, gaining ...
- HDU 3699 A hard Aoshu Problem(暴力枚举)(2010 Asia Fuzhou Regional Contest)
Description Math Olympiad is called “Aoshu” in China. Aoshu is very popular in elementary schools. N ...
- 最短路径——Bellman-Ford算法
一.相关定义 最短路径:求源点到某特定点的最短距离 特点:Bellman-Ford算法主要是针对有负权值的图,来判断该图中是否有负权回路或者存在最短路径的点 局限性:算法效率不高,不如SPFA算法 时 ...
- 望岳物业APP开发过程
望岳物业APP开发过程 1.望岳组员们讨论决定了做的项目及模块功能. 2.物业管理APP图标设计以及写项目的ER图,主要功能流程图. 3.项目体系结构设计和界面设计. 4.了解物业APP的几个功能,然 ...
- [译]如何去除Git的unstaged的文件提示“old mode 100755 new mode 100644”?
原文来源:https://stackoverflow.com/questions/1257592/how-do-i-remove-files-saying-old-mode-100755-new-mo ...
- 判断python字典中key是否存在的两种方法
今天来说一下如何判断字典中是否存在某个key,一般有两种通用做法,下面为大家来分别讲解一下: 第一种方法:使用自带函数实现. 在python的字典的属性方法里面有一个has_key()方法,这个方法使 ...
- linux之shell脚本学习篇一
此文包含脚本服务请求,字符串截取,文件读写内容,打印内容换行. #!/bin/bashretMsg="";while read LINEdo echo "t ...