在Linux/UNIX 下,有下面这五种I/O 操作方式:
1.阻塞 I/O
2. 非阻塞 I/O
3.I/O 多路复用
4.信号驱动 I/O(SIGIO)
5.异步 I/O
至于每种模式的含义自己去查吧,百度百科、wiki百科介绍的都很详细,要是介绍的话,我也就是抄袭过来,要学会使用搜索引擎~~
还记得上一篇文章的例子吧,那就是基于阻塞I/O模式的,简单的不能再简单的socket通信,写那篇主要是为了对socket通信有个简单的认识及明白各个函数的使用方法,以下是为更深一步做基础。
这篇要介绍下I/O多路复用,重要的函数:
1.select()
#include <sys/time.h>
#include <unistd.h>
int select(int maxfd,fd_set *rdset,fd_set *wrset,fd_set *exset,struct timeval *timeout);
参数maxfd是需要监视的最大的文件描述符值+1;
rdset,wrset,exset分别对应于需要检测的可读文件描述符的集合,可写文件描述符的集 合及异常文件描述符的集合。
struct timeval结构用于描述一段时间长度,如果在这个时间内,需要监视的描述符没有事件发生则函数返回,返回值为0。
注意:关于返回值问题,若有就绪描述符则为其数目,若超时则为0,若出错则为1
2.几个重要的宏
FD_CLR(inr fd,fd_set* set);用来清除描述词组 set中相关 fd的位
FD_ISSET(int fd,fd_set *set);用来测试描述词组 set中相关 fd的位是否为真
FD_SET(int fd,fd_set*set);用来设置描述词组 set中相关 fd的位
FD_ZERO(fd_set *set);用来清除描述词组 set的全部位参数
3.一个重要的结构体
timeout为结构 timeval,用来设置 select()的等待时间,其结构定义如下:
struct timeval
{
time_t tv_sec;
time_t tv_usec;
};
下面是常见的程序片段
fs_set readset;
FD_ZERO(&readset);
FD_SET(fd,&readset);
select(fd+1,&readset,NULL,NULL,NULL);
if(FD_ISSET(fd,readset){……}
完成的代码例子:
- #include <stdio.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <unistd.h>
- #define TIMEOUT 5 /* select timeout in seconds *
- #define BUF_LEN 1024 /* read buffer in bytes */
- int main (void)
- {
- struct timeval tv;
- fd_set readfds;
- int ret;
- /* Wait on stdin for input. */
- FD_ZERO(&readfds);
- FD_SET(STDIN_FILENO, &readfds);
- /* Wait up to five seconds. */
- tv.tv_sec = TIMEOUT;
- tv.tv_usec = 0;
- /* All right, now block! */
- ret = select (STDIN_FILENO + 1,&readfds,NULL,NULL,&tv);
- if (ret == -1)
- {
- perror("select");
- return 1;
- }
- else if (!ret)
- {
- printf ("%d seconds elapsed.\n", TIMEOUT);
- return 0;
- }
- /*
- * Is our file descriptor ready to read?
- * (It must be, as it was the only fd that
- * we provided and the call returned
- * nonzero, but we will humor ourselves.)
- */
- if (FD_ISSET(STDIN_FILENO, &readfds))
- {
- char buf[BUF_LEN+1];
- int len;
- /* guaranteed to not block */
- len = read (STDIN_FILENO, buf, BUF_LEN);
- if (len == -1)
- {
- perror ("read");
- return 1;
- }
- if (len)
- {
- buf[len]='\0';
- printf ("read: %s\n", buf);
- }
- return 0;
- }
- fprintf (stderr, "This should not happen!\n");
- return 1;
- }
代码不是很长,是一个最简单的例子,很好理解。
FROM; http://blog.csdn.net/xluren/article/details/8045028