select、pselect、poll和epoll函数是unix中具有I/O复用的函数。什么是I/O复用?为什么要有I/O复用?以及在什么场合下使用I/O复用?既然都具有I/O复用的功能,那这几个函数又有什么样的区别与联系呢?在下面我会一一解释。

请看下面一段客户端代码:

 #include    “unp.h”

 int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
void sig_chld(int); listenfd = Socket(AF_INET, SOCK_STREAM, ); bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT); Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); Listen(listenfd, LISTENQ); Signal(SIGCHLD, sig_chld); /* must call waitpid() */ for ( ; ; )
{
clilen = sizeof(cliaddr);
if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < )
{
if (errno == EINTR)
continue; /* back to for() */
else
err_sys(“accept error”);
} if ( (childpid = Fork()) == )
{ /* child process */
Close(listenfd); /* close listening socket */
str_echo(connfd); /* process the request */
exit();
} Close(connfd); /* parent closes connected socket */
}
}

从以上代码,我们可以知道,这个TCP客户端在同时处理两个输入:标准输入和TCP套接口。现在假设我们遇到了以下问题:

客户阻塞于(标准输入上的)fgets调用期间,服务器进程会被杀死。服务器TCP虽然正确地给客户TCP发送一个FIN,但是既然客户进程阻塞于从标准输入读入的过程,它直到从套接口读时才会看到这个文件结束符(可能已经过了很长时间)。我们需要有这样的能力:如果一个或者多个I/O条件满足(例如:输入已准备好,或者描述字可以承接更多的输出)时,我们就被通知到。这个能力称为I/O复用,是由函数select、poll、epoll支持的。

一般输入操作有两个不同的阶段:

1. 等待数据准备好;

2. 从内核到进程拷贝数据。

1. select函数

int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout);

  • maxfdp1:表示要被测试的最大描述字加1(从参数maxfdp1命名我们可以略知一二);
  • readset、writeset、exceptset: 指定我们要让内核测试读、写和异常条件的描述字;

那么在设计上有一个问题,如何为这三个参数的每一个指定一个或多个描述字值。函数select使用描述字集,它一般是一个整数数组,每个整数中的每一位对应一个描述字。例如,用32位整数数组,那么数组的第一个元素的第一个元素对应于描述字0到31,数组的第二个元素对应于描述字32到63,以此类推。

每一个描述字是如何与fd_set集合中的每一个一一对应的呢?就是用到了下面的四个与select函数相关的宏:

FD_ZERO(fd_set *fdset):清空fdset与所有描述字的联系。  

FD_SET(int fd, fd_set *fdset):建立描述字fd与fdset的联系。  

FD_CLR(int fd, fd_set *fdset):清除描述字fd与fdset的联系。  

FD_ISSET(int fd, fd_set *fdset):检查fdset联系的描述字fd是否可读写,当>0表示可读写。

  • timeout: 它告诉内核花多长时间等待一组指定的描述字中的任一个准备好。

有三种可能:

a. 永远等待下去:仅在有一个描述字准备好I/O时才返回,为此,我们将参数timeout设置为空指针;

b. 等待固定时间:在有一个描述字准备好I/O时返回,但不超过由timeout参数所指定的时间。若超过时间则直接返回;

c. 根本不等待:检查描述字后立即返回,这称为轮询(polling)。为了实现这一点,参数timeout必须指向结构timeval,且定时器的值(由结构timeval指定的秒数和微秒数)必须为0

在前两者情况的等待中,如果进程捕获了一个信号并从信号处理程序返回,那么等待一般被中断。

中间三个参数readset,wirteset和exceptset指定我们要让内核测试读写和异常条件所需的描述字,参数maxfdp1说明了被测试的描述符的个数,它的值是要被测试的最大的描述符加1.

select、pselect、poll和epoll的区别的更多相关文章

  1. select&pselect/poll&ppoll/epoll

    select/pselect, poll和epoll的区别 select,epoll,poll比较 select,poll,epoll进化 Handling of asynchronous event ...

  2. [转帖]select提高并发,select和poll、epoll的区别(杂)

    同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. https://www.2cto.com/kf/20161 ...

  3. select、poll、epoll的区别

    本文写于2017-02-26,从老账号迁移到本账号,原文地址:https://www.cnblogs.com/huangweiyang/p/6444746.html select.poll.epoll ...

  4. select、poll和epoll的区别(转载)

    select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作.但select ...

  5. select、poll和epoll的区别

    操作系统在处理io的时候,主要有两个阶段: 等待数据传到io设备 io设备将数据复制到user space 我们一般将上述过程简化理解为: 等到数据传到kernel内核space kernel内核区域 ...

  6. java面试题之select、poll和epoll的区别

    消息传递方式: select:内核需要将消息传递到用户空间,需要内核的拷贝动作: poll:同上: epoll:通过内核和用户空间共享一块内存来实现,性能较高: 文件句柄剧增后带来的IO效率问题: s ...

  7. select,poll,epoll,selectors

    一 了解select,poll,epoll IO复用:为了解释这个名词,首先来理解下复用这个概念,复用也就是共用的意思,这样理解还是有些抽象, 为此,咱们来理解下复用在通信领域的使用,在通信领域中为了 ...

  8. 以python理解Linux的IO多路复用,select、poll、epoll

    题外话 之前在看Unix环境高级编程的时候,看完高级IO那一章,感觉自己萌萌哒,0.0 ,有点囫囵吞枣的感觉,之后翻了几篇博客,从纯系统的角度理解,稍微有了点概念,以这两篇为例,可以以后参考: htt ...

  9. 10 select、poll以及epoll

    IO复用:为了解释这个名词,首先来理解下复用这个概念,复用也就是共用的意思,这样理解还是有些抽象,为此,咱们来理解下复用在通信领域的使用, 在通信领域中为了充分利用网络连接的物理介质,往往在同一条网络 ...

  10. select、poll和epoll机制

    一.参考网址 1.select函数及fd_set介绍 2.linux select 函数和 fd_set 用法 2.select.poll和epoll的区别 3.利用select实现IO多路复用TCP ...

随机推荐

  1. UVA-11983-Weird Advertisement(线段树+扫描线)[求矩形覆盖K次以上的面积]

    题意: 求矩形覆盖K次以上的面积 分析: k很小,可以开K颗线段树,用sum[rt][i]来保存覆盖i次的区间和,K次以上全算K次 // File Name: 11983.cpp // Author: ...

  2. 【转】java中byte数组与int类型的转换(两种方式)----不错

    原文网址:http://blog.csdn.net/piaojun_pj/article/details/5903009 java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法, ...

  3. 嵌入式 linux 查看内存

    在Windows系统中查看内存的使用情况很简单,想必大家都已经耳熟能详了,那么在linux系统如何查看内存使用情况呢?下面和大家分享在Linux下查看内存使用情况的free命令: [root@scs- ...

  4. 矩阵(快速幂):COGS 963. [NOI2012] 随机数生成器

    963. [NOI2012] 随机数生成器 ★★   输入文件:randoma.in   输出文件:randoma.out   简单对比 时间限制:1 s   内存限制:128 MB [问题描述] 栋 ...

  5. 【图论】Codeforces 711D Directed Roads

    题目链接: http://codeforces.com/problemset/problem/711/D 题目大意: 给一张N个点N条有向边的图,边可以逆向.问任意逆向若干条边使得这张图无环的方案数( ...

  6. 关于aspx 页面生成html 源码顶部空行不得不说的事儿

    原文引用自 http://www.360doc.com/content/12/0910/21/10504424_235418578.shtml 使用.aspx生成的页面一般都会有一个或多个空行,当然这 ...

  7. vim下缩进及高亮设置

    1.配置文件的位置 在目录 /etc/ 下面,有个名为vimrc的文件,这是系统中公共的vim配置文件,对所有用户都有效.而在每个用户的主目录下,都可以自己建立私有的配置文件,命名为:“.vimrc” ...

  8. Jack Straws(判断线段是否相交 + 并查集)

    /** http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1840    题意:    判断线段 ...

  9. DB2 创建数据库

    0.一些准备工作可能用到的命令 db2cmd --进入db2命令行 db2 list database directory --显示已有的数据库 db2 drop db pcore --删除一个数据库 ...

  10. Spring事务配置的五种方式 巨全!不看后悔,一看必懂!

    前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. ...