免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 17668 | 回复: 10
打印 上一主题 下一主题

关于EINTR和EWOULDBLOCK中断的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-03-11 09:34 |只看该作者 |倒序浏览
1、EINTR中断是不是只有在阻塞模式下才会产生?

2、EWOULDBLOCK是在非阻塞模式下产生的中断,这时和EINTR中断是否含义一致,也就是在非阻塞模式下,是否只需要判断EWOULDBLOCK就可以了?

3、在非阻塞模式下,调用write(int fd,void *vptr,int size)时,系统是先判断
内核缓冲区是否有足够size大小的,内核有多少缓冲区,就拷贝多少,还是如果没有size大小的内核缓冲区,就不拷贝了?(这时需要用户循环调用write)。

论坛徽章:
0
2 [报告]
发表于 2004-03-11 10:09 |只看该作者

关于EINTR和EWOULDBLOCK中断的问题

这个问题说起来话长。
你是想实现write还是想用write?

论坛徽章:
0
3 [报告]
发表于 2004-03-11 10:50 |只看该作者

关于EINTR和EWOULDBLOCK中断的问题

原帖由 "FH" 发表:
这个问题说起来话长。
你是想实现write还是想用write?


主要是对现在流行的N多Writen和Readn版本进行一个分析

有的只判断EWOULDBLOCK(非阻塞模式下),有的只判断EINTR,有的两个都判断(比如论坛上前段时间贴出的银行前置机代码)。并且到底应该怎样处理这两个errno,不同版本的Writen和Readn都有一些细微的差别

论坛徽章:
0
4 [报告]
发表于 2004-03-11 11:23 |只看该作者

关于EINTR和EWOULDBLOCK中断的问题

非阻塞模式下也要判EINTR的,阻塞模式只判EINTR就够了。

论坛徽章:
0
5 [报告]
发表于 2004-03-11 11:46 |只看该作者

关于EINTR和EWOULDBLOCK中断的问题

[quote]原帖由 "FH"]非阻塞模式下也要判EINTR的,阻塞模式只判EINTR就够了。[/quote 发表:


那对这两个errno的处理是否都是一样,重新调用read或者write?

论坛徽章:
0
6 [报告]
发表于 2004-03-11 12:04 |只看该作者

关于EINTR和EWOULDBLOCK中断的问题

EWOULDBLOCK用于非阻塞模式,当然不要重新read/write了,而EINTR只是简单地重新read/write就行了。

论坛徽章:
0
7 [报告]
发表于 2004-03-11 13:45 |只看该作者

关于EINTR和EWOULDBLOCK中断的问题

那看一下如下的代码段:
int readn(int fd,void *vptr,int n)
{
int nleft,nread;
char *ptr;

ptr =vptr;
nleft =n;
while(nleft>;0)
{
if((nread = read(fd,ptr,nleft)) < 0 )
{
if(errno == EINTR)
nread = 0;
else if(errno == EWOULDBLOCK)
continue;
else
return -1;
}else if(nread == 0) /* EOF */
break;
nleft -= nread;
ptr += nread;
}
return (n-nleft);
}


在EINTR和EWOULDBLOCK下的处理其实都是重新循环

论坛徽章:
0
8 [报告]
发表于 2004-03-11 13:55 |只看该作者

关于EINTR和EWOULDBLOCK中断的问题

这个程序是死读的,即对非阻塞的Handle也进行阻塞读,这就失去了非阻塞的意义。

实际上,这个函数的意义是:不管你给我什么样的Handle(阻塞或非阻塞),我都阻塞地读一个包。

论坛徽章:
0
9 [报告]
发表于 2004-03-11 14:33 |只看该作者

关于EINTR和EWOULDBLOCK中断的问题

原帖由 "FH" 发表:
这个程序是死读的,即对非阻塞的Handle也进行阻塞读,这就失去了非阻塞的意义。

实际上,这个函数的意义是:不管你给我什么样的Handle(阻塞或非阻塞),我都阻塞地读一个包。


其实这种阻塞读一般用在读长度比较短的时候,例如读数据包的长度、类型(这和应用层相关)

在读具体的数据包内容时,一般都用纪录缓冲区剩余位置的办法进行非阻塞读取。

另外,我还想请教一下FH大虾,select在返回描述字可读时,再调用read,那read函数什么时候能够成功完全读取内核缓冲区

论坛徽章:
0
10 [报告]
发表于 2004-03-11 14:58 |只看该作者

关于EINTR和EWOULDBLOCK中断的问题

对于非阻塞Handle,只要read到EWOULDBLOCK就可以了;对于阻塞Handle,一般没有办法判断,只能在应用层解决了。

有些应用的情况下,对方发来的包是没有长度信息的,但使用write发包,且包的长度不是很长,这样的情况下,一个read也可以解决问题。

对于以包为单位的数据交换,我觉得应该使用read/write代替send/recv,因为前者是不缓冲的,不会破坏小数据包的完整性;而后者是缓冲的,不容易得到期望的结果,除非包与包之间有足够的时延。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP