select函数与stdio混用的不良后果 (转)
出自:http://www.cppblog.com/mysileng/archive/2013/01/15/197284.html
今天在看UNP6.5节,学习到了select与stdio混用的后果。特此进程实验一番。再实验之前需明确一下几点:
1.stdio流的i/o函数 与 系统i/o函数不同。stdio流函数在用户空间和内核都有缓冲,系统i/o函数只在内核有缓冲,用户空间没有。
2.stdio流的i/o函数缓冲机制:在面对文件时候用的是全缓冲,面对设备的时候用的行缓冲。(等下试验用的是键盘和屏幕),所以实验用的stdio函数采用行行缓冲。
3.select函数对于某一个描述符是否准备好可读可写,是对内核缓冲区中的数据是否达到某一个最低标准,而不是用户缓冲区。也就是说select函数不知道用户缓冲区的存在。
首先写了一个系统i/o函数 简单的select函数程序:
程序给select函数只设置的键盘的描述符。也就是说如果键盘的描述符准备好了就不再阻塞。但是这里有一个问题,解除阻塞后,我们最多只从内核缓冲区读3个字节,这个时候就会有两个情况:
(1)内核空间本来存储的数据就小于等于3个字节,全被读走。那下次再次调用select函数,应该肯定会阻塞的,因为键盘输入的内核缓冲区已经没有数据了。
情况如下(内核空间只有3个字节:1 2 \n):
(2)如果内核空间的数据多余3个字节,但是因为最多只能读3个字节,就必将导致内核中有数据读不完。那么下次再遇到select函数的时候是否会阻塞呢?
情况见下:
当我们输入5个字符时候(1 2 3 4 \n),第一次read掉3个字符,内核空间还剩下2个字符,然后再次碰到select函数,默认情况下如果键盘内核空间字符数大于1,select是不会阻塞键盘描述符的。结果也印证了,又read了2个字节,并没有堵塞。
综上所述select是可以看见内核空间的缓冲区的。那到底能不能看见用户空间缓冲区呢?我们换成stdio流的i/o函数继续实验。
--------------------------------------------------------------------
stdio流的i/o函数使用select函数的程序如下:
程序用stdio流的getc函数从键盘读数据,运行结果如下:
我们输入5个字符(1 2 3 4 \n),结果只输出了1个字符,然后就阻塞了。我们分析一下,首先输入5个字符,这5个字符被放入用户缓冲区,因为最后一个是换行符并且stdio面对设备使用行缓冲机制,所以这5个字符马上接着被从用户缓冲区刷入内核缓冲区。然后调用select函数,select函数发现内核空间中有数据,于是不阻塞返回。接着getc函数从用户空间输出缓冲区取一个字符,因为用户空间输出缓冲区没有数据,于是把内核空间的数据调入一行给用户空间输出缓冲区,然后getc返回。接着又碰上select函数,因为内核缓冲空间的数据已经被放入用户空间输出缓冲区了,所以内核缓冲没有数据,那么select认为键盘没有准备好,所以阻塞。虽然阻塞了,但需要注意的时候这个时候,用户空间是有4个字符数据的,被select函数无视了。
接下来假设我们再输入2个字符(1 \n),将会发生什么呢?
输出一对东西,这是怎么回事,我们继续分析。当输入2个字符(1 \n)的时候,内核空间缓冲没有数据,用户空间输出缓冲有4个字符。2个字符根据上一段同样原理,被刷入内核空间缓冲区。select函数被调用,发现有2个字符,于是不阻塞返回。getc函数从用户输出缓冲取出一个字符,打印stardard... --2然后返回。再次循环,调用select函数。关键来了,这里跟上次不一样了。这个时候内核空间的缓冲中还有上次遗留的2个字符,所以依然不阻塞返回,调用getc函数继续打印。。。这里的关键是,getc函数。getc函数在用户输出缓冲中有数据的时候,不会把内核空间缓冲中的数据移入用户空间的输出缓冲,使得内核空间缓冲一直留有数据。这将会持续到用户空间输出缓冲的数据被取完为止。所以上述奇怪的打印结果就可以解释的了。
综上所述,select函数确实是看不见用户空间缓冲的寻在的。
所以如果在使用select函数的时候,要谨慎使用stdio流函数。
select函数与stdio混用的不良后果 (转)的更多相关文章
- select与stdio混合使用的不良后果
参考以下链接自己补充实验:http://www.cppblog.com/mysileng/archive/2013/01/15/197284.aspx?opt=admin int main(int a ...
- select函数实例代码
select函数简解: selct 称之为多路复用IO,使用它可以让程序阻塞在select上,而非实际IO函数上. int select(int nfds, fd_set *readfds, fd_s ...
- select 函数1
Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect.accept.recv或recvfrom这样的阻塞程序( ...
- IO复用与select函数
socket select函数的详细讲解 select函数详细用法解析 http://blog.chinaunix.net/uid-21411227-id-1826874.html linu ...
- 异步套接字基础:select函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET
参考:[原创]技术系列之 网络模型(三)多路复用模型 select函数 select函数: 系统提供select函数来实现多路复用输入/输出模型.原型: #include <sys/time.h ...
- Linux下select函数的使用
一.Select 函数详细介绍 Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect. accept.recv ...
- linux c语言 select函数用法
linux c语言 select函数用法 表头文件 #i nclude<sys/time.h> #i nclude<sys/types.h> #i nclude<unis ...
- select函数的介绍和使用
我们所使用的I/O模型一共有五种. 分别为阻塞I/O,非阻塞I/O,I/O复用,信号驱动I/O,异步I/O. 所谓I/O复用就是指管理多个I/O文件描述符,一般会使用(select,poll,epol ...
- UNIX网络编程——select函数的并发限制和 poll 函数应用举例
一.用select实现的并发服务器,能达到的并发数,受两方面限制 1.一个进程能打开的最大文件描述符限制.这可以通过调整内核参数.可以通过ulimit -n来调整或者使用setrlimit函数设置, ...
随机推荐
- C++ string头文件
转载自https://blog.csdn.net/superna666/article/details/52809007/ 作者 zhenzhenjiajia888 标准c++中string类函数介绍 ...
- 教程笔记《JavaScript深入浅出》
一.数据类型 javascript是弱数据类型语言,不需要显式的定义类型,一共有如下六种数据类型 五种基本类型:number,string,boolean,null,undefined 一种复合类型: ...
- python 数据结构与算法之排序(冒泡,选择,插入)
目录 数据结构与算法之排序(冒泡,选择,插入) 为什么学习数据结构与算法: 数据结构与算法: 算法: 数据结构 冒泡排序法 选择排序法 插入排序法 数据结构与算法之排序(冒泡,选择,插入) 为什么学习 ...
- Java求字符串中出现次数最多的字符
Java求字符串中出现次数最多的字符 [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/51933611 Java ...
- Python9-网络编程3-day32
解决黏包的问题 #server import socket sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() conn,addr ...
- python数据类型之集合(set)和其常用方法
集合是一个无序的,不重复的数据组合 作用(集合的重点):1.去重,把一个列表变成集合就自动去重了2.关系测试,测试两组数据库之前的交集.差集.并集等关系 s = {1, 1, 2, 2, 3, 4, ...
- ProC第三弹
一.前言 我们上面已经了解Windows和Linux下的ProC开发环境,这里我们更进一步去简要介绍下ProC的预编译参数. 二.什么是预编译 预编译过程中,Pro*C/C++会自动生成C或者C++的 ...
- nordic芯片开发——烧写方法记录
在开发nordic芯片的时候,分为存外设开发和结合softdevice开发,另外还有结合mbr的开发(这个暂时没有深究)在裸机开发的时候,sdk里面称为blank,把芯片的程序erase之后,直接下载 ...
- POJ:2060-Taxi Cab Scheme(最小路径覆盖)
传送门:http://poj.org/problem?id=2060 Taxi Cab Scheme Time Limit: 1000MS Memory Limit: 30000K Total Sub ...
- 新游发布:《Don't touch the color》
这是笨猫工作室最后一个Scratch 2.0游戏,经过笨猫工作室成员的不懈努力,游戏终于可以稳定运行.此次更新添加了最高分数显示,优化了系统流畅度.快来试玩吧!!! 卡搭蓝链:https://kada ...