I/O多路转接 --- UNIX环境高级编程
I/O多路转接技术:先构造一张有关描述符的列表,然后调用一个函数,知道这些描述符中的一个已准备好进行I/O时,给函数才返回。在返回时,它告诉进程哪些描述符已准备好可以进行I/O。
poll、select、pselect这三个函数使我们能够执行I/O多路转接。
1.select和pselect函数
I/O多路转接的标准函数,还有一个标准函数poll函数,就这两个
该函数主要用于终端I/O和网络I/O,但它对其他描述符同样起作用。
#include <sys/selecet.h>
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
传向select的参数告诉内核,我们所关心的描述符;对于每个描述符我们所关心的状态;愿意等待多长时间;返回值告诉我们,已准备好的的描述符的数量;对于读、写、异常者三个状态中的每一个,哪些描述符已准备好;所以,只用这些返回值,就可调用相应的I/O函数(一般是read和write),并且确知该函数不会阻塞。
参数意义:
timeout:它指等待的时间:struct timeval{ long tv_sec; long tv_usec; };
timeout = NULL; 永远等待。如果捕捉到一个信号则终端此无限期等待。当所指定的描述符中的一个已准备好或捕捉到一个信号则返回。如果捕捉到信号一个信号,则返回-1,errno设置为EINTR。
timeout->tv_sec == 0 && timeout->tv_usec == 0; 完全不等待。测试所有描述符并立即返回。
timeout->tv_sec != 0 && timeout->tv_usec != 0; 等待指定的秒数和微秒数。当指定的描述符之一已准备好,或当指定的时间值已经超过时立即返回。超时但没有一个描述符准备好则返回0,
中间3个参数readfds、writefds、exceptfds是指向描述符集的指针。这三个描述符集说明了我们关心的可读、可写、=或异常条件的哥哥描述符。每个描述符集存放在一个fs_set数据类型中。这种数据类型为每一可能的描述符保持了一位。
#include <sys/select.h>
void FD_CLR(int fd, fd_set *set); 将指定位清掉
int FD_ISSET(int fd, fd_set *set); 测试仪指定位是否设置;若fd在集中则返回非0,否则返回0;
从select返回时,用其测试该集中的一个给定位是否仍旧设置
void FD_SET(int fd, fd_set *set); 设置一个指定位
void FD_ZERO(fd_set *set); 清楚所有位,在声明一个描述符集后,必须先清楚所有位。
中间的三个参数中任意一个或全部都可是NULL,表示对相应的状态不关心,如果都为空指针,则select提供了较sleep更精确的定时。
第一个参数nfds,“最大描述符加1”。在3个描述符集中,找出最大描述符编号值,然后加1,就是第一个参数的值。第一个参数实际是要检查的描述符的个数
返回值:
-1。表示出错,例如在所指定的描述符都没有准备好时捕捉到一个信号,在此情况下,将不修改其中任何描述符集。
0。表示没有描述符准备好。指定的描述符都没有准备好,指定的时间已经超过,则发生这种情况。此时,所有的描述符皆被清0。
正返回值。表示已准备好的描述符的个数。是3个描述集中已准备好的描述符数之和,所以同一个描述符已准备好好读和写,返回值中将其记为2.
对于“已准备好”的意思做一些具体说明:
若对读集(readfds)中的一个描述符的read操作将不会阻塞,则此描述符准备好了
若对写集(writefds)中的一个描述符的write操作将不会阻塞,则此描述符准备好了
若异常状态急(exceptfds)中个一个描述符有一个未决异常状态,则此描述符准备好了
对于读、写、异常状态,普通文件描述符总是返回准备好。
一个描述符阻塞与否并不影响select是否阻塞。
如果在一个描述符上碰到了文件结尾处,则select认为该描述符是可读的,然后调用read,返回0。不要认为到达结尾处,select会只是一个异常状态。
POSIX.1也定义了一个select的变体,它被称为pselect
#include <sys/select.h>
int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
除了一下几点外,pselect与select相同:
2.poll函数(多路I/O转接的标准函数之一,还有一个select)
与select函数类似,返回值与select相同
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
与select不同,poll不是为每个状态(读、写、异常)构造一个描述符集,而是构造一个pollfd结构体数组。每个数组元素指定一个描述符编号以及对其关心的状态。
参数:
第一个参数是结构体数组。struct pollfd{int fd; short events; short revents; };
每个数组元素的events成员设置的值见表,通过这些值告诉内核我们对描述符关心的是什么。返回时,内核设置revents成员,说明对该描述符已经发生了什么
【注意】poll函数没有更改events成员,这与select不同,select修改其参数以指示哪一个描述符已准备好。
当一个描述符被挂断(POLLHUP)后,就不能再写向该描述符。但仍可能从该描述符读取到数据
第二个参数,nfds。fds数组中的元素数由nfds说明
第三个参数timeout。
-1.永远等待。返回值情况与select相同
0.不等待。测试所有描述符并立即返回。
>0。等待timeout毫秒。返回值情况与select相同。
【注】如果系统不提供毫秒级分辨率,则timeout值取整到最近的支持值。
文件结束与挂断之间的区别。
如果正从终端输入数据,并键入文件结束字符,POLLIN打开,于是就可读文件结束指示(read返回0)。POLLHUP在revents中没有打开。
如果正在读调制解调器,并且电话线已挂断,则在revents中将接到POLLHUP通知。
与select一样。不论一个描述符是否阻塞,都不影响poll是否阻塞。
I/O多路转接 --- UNIX环境高级编程的更多相关文章
- (十一) 一起学 Unix 环境高级编程 (APUE) 之 高级 IO
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- 《UNIX环境高级编程(第3版)》
<UNIX环境高级编程(第3版)> 基本信息 原书名:Advanced Programming in the UNIX Environment (3rd Edition) (Addison ...
- (十三) [终篇] 一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- multiple definition of `err_sys' 《UNIX环境高级编程》
本文地址:http://www.cnblogs.com/yhLinux/p/4079930.html 问题描述: [点击此处直接看解决方案] 在练习<UNIX环境高级编程>APUE程序清单 ...
- unix环境高级编程基础知识之第二篇(3)
看了unix环境高级编程第三章,把代码也都自己敲了一遍,另主要讲解了一些IO函数,read/write/fseek/fcntl:这里主要是c函数,比较容易,看多了就熟悉了.对fcntl函数讲解比较到位 ...
- (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (四) 一起学 Unix 环境高级编程(APUE) 之 系统数据文件和信息
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
随机推荐
- 安装 vs2005, vs2008 报错
最近重新装了系统之后,在安装 vs2005, vs2008 到如下类似的错误,苦苦两天没有解决.不要问为什么是 vs2005,vs2008, 因为原有的项目就是老版本. 无意间在网上看到一句话,大意是 ...
- ASP.NET协作应用集成到trsids身份验证服务器的开发流程
开发Actor协同模块: (参考TRSIDS4.0 协作应用集成手册[asp.net]) ASP.Net协作应用集成到IDS之前,需要开发Actor类实现协作应用回调接口中定义的本地登录.退出.用户信 ...
- CSS3 字体
CSS3 @font-face 规则 在 CSS3 之前,web 设计师必须使用已在用户计算机上安装好的字体. 通过 CSS3,web 设计师可以使用他们喜欢的任意字体. 当您您找到或购买到希望使用的 ...
- 《CSS网站布局实录》学习笔记(五)
第五章 CSS内容排版 5.1 文字排版 5.1.1 通栏排版 进行网页通栏排版时,只要直接将段落文字放置于p或者其他对象中,再对段落文字应用间距.行距.字号等样式控制,便形成了排版雏形. 5.1.2 ...
- MD5加密类
public class MD5Util { public static String getMD5(String s) { char hexDigits[] = {'0', '1', '2', '3 ...
- Entity Framework 新增实体,新增抽象实体
抽象实体不能new 抽象类:人,实体类:学生 人 p_人= new 学生(); 添加数据,学生和人都添加 抽象类可以提供一个抽象的方法,但是并没有实现,类似接口,但又不同于接口.子类继承父类时必须 ...
- 使用UILocalNotification给App添加本地消息通知
使用过的代码,直接贴上 UILocalNotification *notification = [[UILocalNotification alloc] init]; if (notification ...
- Centos 中 vim 的配置
工欲善其事,必先利其器,我们要用好 vim 就先来把它配置的顺手一点,这样可以大大提高我们的工作学习效率 1.跳转指令 Ctags1 从下面地址下载ctags,将其中的ctags.exe复制到vim目 ...
- printf格式输出总结
#include<stdio.h> #include<string.h> int main() { ]; ; floa ...
- DropdownList控件绑定数据源显示system.data.datarowview的问题
.net开发的时候经常需要用到在后台取数据再绑定到控件的问题,通常只需要连接数据库,从数据库取出数据,放到Dataset里面,然后再设置控件的DataSource为这个Dataset,然后再datab ...