I/O多路转接模型
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多路转接模型的更多相关文章
- 多路转接模型之poll
poll系统调用和select类似.也是在指定时间内轮询一定数量的文件描写叙述符,以測试当中是否有就绪者.poll和select效率差点儿相同,仅仅是其使用接口相对简单些,poll不在局限于1024个 ...
- Linux下I/O多路转接之select --fd_set
fd_set 你终于还是来了,能看到这个标题进来的,我想,你一定是和我遇到了一样的问题,一样的疑惑,接下来几个小时,我一定竭尽全力,写出我想说的,希望也正是你所需要的: 关于Linux下I/O多路转接 ...
- 高级I/O之I/O多路转接——pool、select
当从一个描述符读,然后又写到另一个描述符时,可以在下列形式的循环中使用阻塞I/O: ) if (write(STDOUT_FILENO, buf, n) != n) err_sys("wri ...
- IO多路转接select和poll
select IO多路复用的设置方法与信号的屏蔽有点相似: 信号屏蔽需要先设定一个信号集, 初始化信号集, 添加需要屏蔽的信号, 然后用sigprocmask设置 IO多路转接需要先设定一个文件描述符 ...
- I/O多路转接 --- UNIX环境高级编程
I/O多路转接技术:先构造一张有关描述符的列表,然后调用一个函数,知道这些描述符中的一个已准备好进行I/O时,给函数才返回.在返回时,它告诉进程哪些描述符已准备好可以进行I/O. poll.selec ...
- Linux下I/O多路转接之epoll(绝对经典)
epoll 关于Linux下I/O多路转接之epoll函数,什么返回值,什么参数,我不想再多的解释,您不想移驾,我给你移来: http://blog.csdn.net/colder2008/artic ...
- UNIX环境高级编程——I/O多路转接(select、pselect和poll)
I/O多路转接:先构造一张有关描述符的列表,然后调用一个函数,直到这些描述符中的一个已准备好进行I/O时,该函数才返回.在返回时,它告诉进程哪些描述符已准备好可以进行I/O. poll.pselect ...
- select函数与I/O多路转接
select函数与I/O多路转接 相作大家都写过读写IO操作的代码,例如从socket中读取数据可以使用如下的代码: while( (n = read(socketfd, buf, BUFSIZE) ...
- I/O多路转接-epoll
By francis_hao Aug 5,2017 APUE讲多路转接的章节介绍了select.pselect和poll函数.而epoll是linux内核在2.5.44引入的.在glibc ...
随机推荐
- mui 区域三级联动
<link href="../../css/mui.picker.css" rel="stylesheet" /><link href=&qu ...
- Google PageSpeed Tools 性能测试分析
今天给大家介绍下一个工具:Google PageSpeed Tools,根据官方的介绍,简单梳理如下: Page Speed Insights能针对移动设备和电脑设备衡量网页的性能.该工具会抓取网址两 ...
- ECMAScript 5 新特性
Strict模式 开启strict: 在文件头部,或者在一个function头部内,添加‘use strict’或者“use strict”. Strict模式的限制,以及违反时出现的异常: 新定制了 ...
- CentOS 6.*通过yum安装 MySQL-5.5
转自https://www.cnblogs.com/wsl222000/p/5445768.html 1.安装mysql-5.5的yum源 rpm -ivh http://repo.mysql.com ...
- 高级设置电脑系统windows7防火墙出错代码0×6D9原因与解决技巧
高级设置windows防火墙能够更好的保护电脑系统安全,在电脑系统windows7设置过程中难免会遇到某些问题,有用户在安装MRGT后想要打开SNMP的161端口,但在打开高级安全windows防火墙 ...
- css3图片动画旋转
body{ background-color:#021E36; text-align: center; } .container{margin:500px auto;} .round{position ...
- ADO.NET复习总结(2)--连接池
1. 2. 3.示例:在一百次循环中,执行数据库连接的打开和关闭,使用stopwatch查看所用的时间. using System; using System.Collections.Generic; ...
- 系列3|走进Node.js之多进程模型
文:正龙(沪江网校Web前端工程师) 本文原创,转载请注明作者及出处 之前的文章"走进Node.js之HTTP实现分析"中,大家已经了解 Node.js 是如何处理 HTTP 请求 ...
- Android知识点剖析系列:深入了解layout_weight属性
摘录自:http://www.cnblogs.com/net168/p/4227144.html 前言 Android中layout_weight这个属性对于经常捣鼓UI的我们来说,肯定不会陌生.但是 ...
- C# WinForm程序退出的方法比较
1.this.Close(); 只是关闭当前窗口,若不是主窗体的话,是无法退出程序的,另外若有托管线程(非主线程),也无法干净地退出: 2.Application.Exit(); 强制所有消息中 ...