Linux下I/O复用 Select与Poll

Select

#include <sys/time.h>
#include <sys/types.h>
#include <sys/unistd.h>

int select (int n, fd_set readfds, fd_set writefds,
fd_set exceptfds, struct timeval timeout);

FD_CLR(int fd, fd_set *set);
FD_ISSET(int fd, fd_set *set);
FD_SET(int fd, fd_set *set);

FD_ZERO(fd_set *set);

调用select 将受到阻塞,必须等到指定的文件描述符就绪可进行I/O,或者等到一个指定的事件限额过去。

此调用所监视的文件描述符分为三种事件类型,每个等待不同的事件。readfds中的文件描述符是准备读取的;writefds
分组中的文件描述符是准备写入数据的; exceptfds 分组的中的文件描述符是用于查看是否有异常发生或紧急数据可用。这三个分组可以是NULL,在此情况下
select() 将无法监视相应的事件。

此调用返回后,每个分组只会包含就绪可进行I/O的文件描述符。

第一个参数 n 等于任何分组中最高编号的文件描述符的值加1。

timeout 参数是一个指向 timeval 结构的指针,该结构的定义如下:
struct timeval {

long tv_sec;

seconds long tv_usec;

microseconds

};

如果此参数不是 NULL,则 select() 调用将在 tv_sec 秒与 tv_usec
微秒之后返回,即使尚无任何文件描述符就绪可进行I/O。如果 timeout
的这两个值都被设为零,则此调用会立即返回,报告此调用进行的时候是否有任何事件等待处理,但是不会等待其后的任何事件。

fd_set writefds;
FD_ZERO(&writefds);
FD_SET(fd,&writefds); //将fd加入分组
FD_CLR(fd,&writedfds); //从分组移除fd 
FD_ISSET(fd,&writefds); //测试特定文件描述符是否已就绪 


 1 #include <stdio.h>
2 #include <sys/time.h>
3 #include <sys/types.h>
4 #include <unistd.h>
5
6 #define TIMEOUT 5
7 #define BUF_LEN 1024
8
9 int main()
10 {
11 struct timeval tv;
12 fd_set readfds;
13
14 FD_ZERO(&readfds);
15 FD_SET(STDIN_FILENO, &readfds);
16
17 tv.tv_sec = TIMEOUT;
18 tv.tv_usec = 0;
19
20 ret = select (STDIN_FILENO+1, &readfds, NULL,NULL,&tv);
21
22 if (FD_ISSET (STDIN_FILENO, &readfds)) {
23 char buf[BUF_LEN+1];
24 int len = read(STDIN_FILENO, buf, BUF_LEN);
25
26 buf[len] = 0;
27 printf("read:%s\n",buf);
28 }
29 }




poll

#include <sys/poll.h>

int poll (struct pollfd *fds, unsigned int nfds, int timeout);

struct pollfd {
    int fd; //文件描述符

short events; //所要查看的事件

short revents; //返回所目击事件
};

每个 pllfd 结构可用于制定一个要查看的文件描述符。每个pollfd结构的 events
字段是该文件描述符所要查看事件的位掩码,用户可以设定此字段。而 revents 字段则是该文件描述符所目击事件的位掩码,内核会在返回时设定此字段。

有效事件包括:
POLLIN 有数据可供读取
OLLRDNORM 有一般数据可供读取
POLLRDBAND
有优先数据可供读取
POLLPRI 有紧急数据可供读取
POLLOUT 写入操作将不受阻塞
POLLWRNORM
写入一般数据将不受组阻塞
POLLWRBAND 写入优先数据将不受阻塞
POLLMSG 有SIGPOLL消息可用
POLLER
所指定的文件描述符发生错误
POLLHUP 所指定的文件描述符发生挂起事件
POLLNVAL 所指定的文件描述符无效

例子:


 1 #include <stdio.h>
2 #include <unistd.h>
3 #include <sys/poll.h>
4
5 #define TIMEOUT 5
6
7 int main()
8 {
9 struct pollfd fds[2];
10 int ret;
11
12 fds[0].fd = STDIN_FILENO;
13 fds[0].events = POLLIN;
14
15 fds[1].fd = STDOUT_FILENO;
16 fds[1].events = POLLOUT;
17
18 int a;
19 //scanf("%d",&a);
20 ret = poll(fds,2,TIMEOUT*1000);
21
22 if (!ret) {
23 perror("poll");
24 return 1;
25 }
26
27 if (!ret) {
28 printf("%d seconds elapsed. \n", TIMEOUT);
29 return 0;
30 }
31
32 if (fds[0].revents & POLLIN)
33 printf("stdin is readable\n");
34
35 if (fds[1].revents & POLLOUT)
36 printf("stdout is writable\n");
37 scanf("%d",&a);
38 return 0;
39 }

时间: 2024-10-21 05:23:26

Linux下I/O复用 Select与Poll的相关文章

Linux多线程编程----IO【select、poll、epoll】

IO操作多   速度就下降 IO数据的 读和写 IO的完成 必须等到 读事件(如磁盘 拷贝  每次要从磁盘查找数据) 和 写事件 (允许写 如写太快 写满就要马上阻塞)的就绪 IO是否高效 :主要看一次IO中 等的时间的比例的多少 (等的时间比例越少  越高效) 就像钓鱼分两步:1 等 2 钓   (评价钓鱼技术高效 是 等的时间少 钓的次数多) 5中IO模型 1 阻塞式IO: 等的时候自己等   , 数据搬迁也是由自己来操作, IO事件就绪时 自己处理.期间什么也不做 2 非阻塞IO :(轮询

linux下多路复用模型之Select模型

Linux关于并发网络分为Apache模型(Process per Connection (进程连接) ) 和TPC , 还有select模型,以及poll模型(一般是Epoll模型) Select模型极其作用:这文章讲述的很好,没必要重述已有的东西,就直接给链接 http://blog.csdn.net/turkeyzhou/article/details/8609360 我的理解: 1 /* According to POSIX.1-2001 */ 2 #include <sys/selec

I/O复用 select和poll

一.I/O模型 1.阻塞式I/O模型: 2.非阻塞式I/O模型 3.I/O复用模型 4.信号驱动式I/O模型 5.异步I/O 信号驱动式I/O和异步I/O之间的区别是:信号驱动式I/O是由内核通知何时可以启动I/O操作,而异步I/O是由内核通知I/O操作何时完成. 二.同步I/O与异步I/O 同步I/O:导致请求进程阻塞,直到I/O操作完成. 异步I/O:不导致请求进程阻塞. I/O模型的比较如下: 原文地址:https://www.cnblogs.com/rabbit0212/p/111691

UNPv1第六章:IO复用select&amp;poll

有些进程需要一种预先告知内核的能力,使得内核一旦发现进程指定的一个或多个I/O条件就绪(也就是说输入已准备好被读取,或者描述符已能承受更多的输出),他就通知进程,这个能力称为I/O复用 1.IO模型 5种基本I/O模型 阻塞式I/O 非阻塞式I/O I/O复用(select和poll) 信号驱动式I/O(SIGIO) 异步I/O 一个输入操作通常包括两个不同的阶段 (1)等待数据准备 (2)从内核向进程复制数据 对于一个套接口上的输入操作,第一步一般是等待数据到达网络,当分组到达时,它被拷贝到内

socket阻塞与非阻塞,同步与异步、I/O模型,select与poll、epoll比较

1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端: 同步:      所谓同步,就是在c端发出一个功能调用时,在没有得到结果之前,该调用就不返回.也就是必须一件一件事做,等前一件做完了才能做下一件事. 例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步:      异步的概念和同步相对.当c端一个异步过程调用发出后,调

Linux中的IO复用接口简介(文件监视?)

I/O复用是Linux中的I/O模型之一.所谓I/O复用,指的是进程预先告诉内核,使得内核一旦发现进程指定的一个或多个I/O条件就绪,就通知进程进行处理,从而不会在单个I/O上导致阻塞. 在Linux中,提供了select.poll.epoll三类接口来实现I/O复用. select函数接口 select中主要就是一个select函数,用于监听指定事件的发生,原型如下: 12345 #include<sys/select.h>#include<sys/time.h>int sele

linux 下 epoll 编程

转载自 Linux epoll模型 ,这篇文章讲的非常详细! 定义: epoll是Linux内核为处理大批句柄而作改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著的减少程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率.因为它会复用文件描述符集合来传递结果而不是迫使开发者每次等待事件之前都必须重新准备要被侦听的文件描述符集合,另一个原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符

Linux网络编程-IO复用技术

IO复用是Linux中的IO模型之一,IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理,从而不会在单个IO上阻塞了.Linux中,提供了select.poll.epoll三种接口函数来实现IO复用. 1.select函数 #include <sys/select.h> #include <sys/time.h> int select(int nfds, fd_set *readfds, fd_set *writef

三种多路复用IO实现方式:select,poll,epoll的区别

select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作.但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间. 此时需知道两个概念: 所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必