body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;} th{border: 1px solid gray; padding: 4px; background-color: #DDD;} td{border: 1px solid gray; padding: 4px;} tr:nth-child(2n){background-color: #f8f8f8;}

I/O多路转接模型:
    在这种模型下,如果请求的I/O操作阻塞,且它不是真正阻塞I/O,而是让其中的一个函数等待,在这期间,I/O还能进行其他操作。
#include <sys/select.h>
#include <sys/time.h>
int select(int maxfd, fd_set *readset, fd_set *writeset, fd_set *exceptionset, const struct timeval* timeout);   \\返回:就绪描述字的正数目,0——超时,-1——出错
参数解释:
maxfd            最大的文件描述符(其值应该为最大的文件描述符字 + 1)
readset          内核读操作的描述符字集合
writeset         内核写操作的描述符字集合
exceptionset     内核异常操作的描述符字集合
timeout          等待描述符就绪需要多少时间。NULL代表永远等下去,一个固定值代表等待固定时间,0代表根本不等待,检查描述字之后立即返回。

其中 readset、writeset、exceptionset 都是 fd_set 集合。该集合的相关操作如下:
void FD_ZERO(fd_set *fdset);               /* 将所有fd清零 */
void FD_SET(int fd, fd_set *fdset);        /* 增加一个fd */
void FD_CLR(int fd, fd_set *fdset);        /* 删除一个fd */
int FD_ISSET(int fd, fd_set *fdset);       /* 判断一个fd是否有设置 */

一般来说,在使用select函数之前,首先要使用FD_ZERO和FD_SET来初始化文件描述符集,在使用select函数时,可循环使用FD_ISSET测试描述符集,在执行完对相关文件描述符之后,使用FD_CLR来清除描述符集(也可以直接用FD_ZERO直接全部清零)。

select函数中的 timeout 是一个 struct timeval 类型的指针,该结构体如下:
struct timeval
{
        long tv_sec;         /* second */         //秒
        long tv_usec;        /* microsecond */    //微秒
};


流程:

fd_set readset;
FD_SET(0,&readset);
FD_SET(fdr,&readset);
int ret=select(fdr+1,&readset,NULL,NULL,NULL);
if(ret >0)
{
     if(FD_ISSET(0,&readset))
     {
     }
     if(FD_ISSET(fdr,&readset))
     {
     }
}

select 监控哪些描述符可以读

a.c b.c
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/time.h>
#include<unistd.h>
#include<stdio.h>
#include<strings.h>
#include<string.h>
int main(int argc,char** argv)
{
        int fdw=open(argv[1],O_RDWR);
        int fdr=open(argv[2],O_RDWR);
        printf("fdw=%d fdr=%d\n",fdw,fdr);
        char buf[128]="";
        fd_set rdset;
        int ret;
        while(1)
        {
                FD_ZERO(&rdset);
                FD_SET(0,&rdset);
                FD_SET(fdr,&rdset);
                ret=select(fdr+1,&rdset,NULL,NULL,NULL);
                if(ret>0)
                {
                        if(FD_ISSET(0,&rdset))
                        {
                                bzero(buf,sizeof(buf));
                                read(0,buf,sizeof(buf));
                                write(fdw,buf,strlen(buf)-1);  //从控制终端读的时候,回车也会读进去,所以要-1去掉回车
                        }
                        if(FD_ISSET(fdr,&rdset))
                        {
                                bzero(buf,sizeof(buf));
                                read(fdr,buf,sizeof(buf));
                                printf("b:%s\n",buf);
                        }
                }
        }
        return 0;
}

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/time.h>
#include<unistd.h>
#include<stdio.h>
#include<strings.h>
#include<string.h>
int main(int argc,char** argv)
{
        int fdr=open(argv[1],O_RDWR);
        int fdw=open(argv[2],O_RDWR);
        printf("fdr=%d fdw=%d\n",fdr,fdw);
        char buf[128]="";
        fd_set rdset;
        int ret;
        while(1)
        {
                FD_ZERO(&rdset);
                FD_SET(0,&rdset);
                FD_SET(fdr,&rdset);
                ret=select(fdr+1,&rdset,NULL,NULL,NULL);
                if(ret>0)
                {
                        if(FD_ISSET(0,&rdset))
                        {
                                bzero(buf,sizeof(buf));
                                read(0,buf,sizeof(buf));
                                write(fdw,buf,strlen(buf)-1);
                        }
                        if(FD_ISSET(fdr,&rdset))
                        {
                                bzero(buf,sizeof(buf));
                                read(fdr,buf,sizeof(buf));
                                printf("a:%s\n",buf);
                        }
                }
        }
        return 0;
}

I/O多路转接模型的更多相关文章

  1. 多路转接模型之poll

    poll系统调用和select类似.也是在指定时间内轮询一定数量的文件描写叙述符,以測试当中是否有就绪者.poll和select效率差点儿相同,仅仅是其使用接口相对简单些,poll不在局限于1024个 ...

  2. Linux下I/O多路转接之select --fd_set

    fd_set 你终于还是来了,能看到这个标题进来的,我想,你一定是和我遇到了一样的问题,一样的疑惑,接下来几个小时,我一定竭尽全力,写出我想说的,希望也正是你所需要的: 关于Linux下I/O多路转接 ...

  3. 高级I/O之I/O多路转接——pool、select

    当从一个描述符读,然后又写到另一个描述符时,可以在下列形式的循环中使用阻塞I/O: ) if (write(STDOUT_FILENO, buf, n) != n) err_sys("wri ...

  4. IO多路转接select和poll

    select IO多路复用的设置方法与信号的屏蔽有点相似: 信号屏蔽需要先设定一个信号集, 初始化信号集, 添加需要屏蔽的信号, 然后用sigprocmask设置 IO多路转接需要先设定一个文件描述符 ...

  5. I/O多路转接 --- UNIX环境高级编程

    I/O多路转接技术:先构造一张有关描述符的列表,然后调用一个函数,知道这些描述符中的一个已准备好进行I/O时,给函数才返回.在返回时,它告诉进程哪些描述符已准备好可以进行I/O. poll.selec ...

  6. Linux下I/O多路转接之epoll(绝对经典)

    epoll 关于Linux下I/O多路转接之epoll函数,什么返回值,什么参数,我不想再多的解释,您不想移驾,我给你移来: http://blog.csdn.net/colder2008/artic ...

  7. UNIX环境高级编程——I/O多路转接(select、pselect和poll)

    I/O多路转接:先构造一张有关描述符的列表,然后调用一个函数,直到这些描述符中的一个已准备好进行I/O时,该函数才返回.在返回时,它告诉进程哪些描述符已准备好可以进行I/O. poll.pselect ...

  8. select函数与I/O多路转接

    select函数与I/O多路转接 相作大家都写过读写IO操作的代码,例如从socket中读取数据可以使用如下的代码: while( (n = read(socketfd, buf, BUFSIZE) ...

  9. I/O多路转接-epoll

    By francis_hao    Aug 5,2017   APUE讲多路转接的章节介绍了select.pselect和poll函数.而epoll是linux内核在2.5.44引入的.在glibc ...

随机推荐

  1. SQL强化(二) 在Oracle 中写代码

    一  : 关于查询中的转换 -- 字符串转换 一 : decode 函数 转换 SELECT DECODE ( PROTYPE.PRO_TYPE_DATE, 'L', '长', 'm', '短', ' ...

  2. Node类型知识大全

    Node类型 1.节点关系 每个节点都有一个childNodes属性,其中保存着一个NodeList对象.NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点.请注意, ...

  3. iptables命令 高级网络

    http://man.linuxde.net/iptables iptables命令是Linux上常用的防火墙软件,是netfilter项目的一部分.可以直接配置,也可以通过许多前端和图形界面配置. ...

  4. dede文章插入分页符不起作用,编辑器中出现分页符,导致文章显示不全

    文章来源:小灰博客| 时间:2013-10-30 13:40:21| 作者:Leo | 1 条评论 文章分类:IT技术分享.PHP     标签: dedecms 今天偶尔发现给一篇dede下的长文章 ...

  5. Html Mailto标签详细使用方法

    http://www.360doc.com/content/09/0805/14/16915_4684377.shtml Html Mailto标签详细使用方法 Html中mailto标签是一个非常实 ...

  6. dedecms环境优化

    路径:dedecms/dede/templates/index_body.htm <script type="text/javascript">function sho ...

  7. 月薪20k以上的高级程序员需要学习哪些技术呢?

    课程内容: 源码分析.分布式架构.微服务架构.性能优化.团队协作效率.双十一项目实战 适用对象: 1-5年或更长软件开发经验,没有工作经验但基础非常扎实,对java工作机制,常用设计思想,常用java ...

  8. MySQL 取得小时分钟部分

    MySQL 取得小时分钟部分 SELECT `CpParkID` , DATE_FORMAT( `UPDATE_TIME` , '%H:%i' )FROM `cp_park`WHERE HOUR( ` ...

  9. 一分钟搭建Vue2.0+Webpack2.0多页面项目

    想要自己一步步搭建的比较麻烦,不是很推荐,最少也要使用vue-cli,在其基础上开始搭建,今天我的主题是一分钟搭建,那么常规方法肯定不能满足的, 而我用的方法也很简单,就是使用已经配置完成的demo模 ...

  10. Redis 2种持久化模式的缺陷

    http://blog.csdn.net/hexieshangwang/article/details/47254087 一.RDB持久化模式缺陷 1.问题描述: 并发200路,模拟不断写Redis, ...