多路复用都是在阻塞模式下有效!

linux中的系统调用函数默认都是阻塞模式,例如应用层读不到驱动层的数据时,就会阻塞等待,直到有数据可读为止。

问题:在一个进程中,同时打开了两个或者两个以上的文件,读第一个文件时没有数据阻塞了。程序就停止在此位置等待,可是第二个文件有数据可读了,数据读不到怎么办?

回答:此种问题可以用多路复用 select / poll 完美解决。

多路复用 select / poll :对多个文件描述符进行监控,一旦有文件描述符可读或者可写,就会通知应用程序进行读写。

1、select


// 监控多个文件描述符属性变化,包括可读,可写,出错异常

// 参数1:监控的最大描述符加1

// 参数2:监控的可读描述符集合

// 参数3:监控的可写描述符集合

// 参数4:监控的出错异常描述符集合

// 参数5:监控时间 NULL-永远等待 0-不阻塞 固定时间

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

// 检查指定的文件描述符是否可读写

int FD_ISSET(int fd, fd_set *set);

// 将一个文件描述符加入到监控集合中

void FD_SET(int fd, fd_set *set);

// 将指定文件描述符从集合中删除

void FD_CLR(int fd, fd_set *set);

// 清空集合

void FD_ZERO(fd_set *set);

2、poll

struct pollfd {
    int fd;       /* 监控的文件描述符 */
    short events;   /* 等待的事件 */
    short revents;  /* 发生的事件 */
};

// 监控多个文件描述符的属性变化

// 参数1:文件描述符集合

// 参数2:文件描述符数量

// 参数3:超时时间

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

POLLIN:可读

POLLOUT:可写

POLLERR:出错

------------------------
应用:实现一个poll的接口:

struct pollfd pfd[2];

pfd[0].fd = fd;
pfd[0].events = POLLIN; // 0为标准输入
pfd[1].fd = 0;
pfd[1].events = POLLIN; ret = poll(pfd, 2, -1);
if(ret > 0)
{
// 查询
if(pfd[0].revents & POLLIN)
ret = read(fd, &event, sizeof(struct key_event)); if(pfd[1].revents & POLLIN)
fgets(kbd_buf, 64, stdin);
}

------------------------
驱动:实现一个poll的接口:

unsigned int key_drv_poll(struct file *filp, struct poll_table_struct *pts)
{
// 如果没有数据返回一个0, 有数据返回一个POLLIN
unsigned int mask = 0; //将当前的等待队列头,注册到vfs层
//参数1--文件对象
//参数2--等待队列头
//参数3--当前函数第二参数
poll_wait(filp, &key_dev->wq_head, pts); if(key_dev->have_data)
mask |= POLLIN; return mask;
}

Linux 多路复用 select / poll的更多相关文章

  1. Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)

    Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...

  2. (转)Linux下select, poll和epoll IO模型的详解

    Linux下select, poll和epoll IO模型的详解 原文:http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll ...

  3. 【操作系统】I/O多路复用 select poll epoll

    @ 目录 I/O模式 I/O多路复用 select poll epoll 事件触发模式 I/O模式 阻塞I/O 非阻塞I/O I/O多路复用 信号驱动I/O 异步I/O I/O多路复用 I/O 多路复 ...

  4. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

  5. Linux下select, poll和epoll IO模型的详解

    http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll 介绍 Epoll 可是当前在 Linux 下开发大规模并发网络程序的热 ...

  6. I/O多路复用 select poll epoll

    I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. select select最早于1983年出现在4.2BSD中,它通 ...

  7. IO多路复用select/poll/epoll详解以及在Python中的应用

    IO multiplexing(IO多路复用) IO多路复用,有些地方称之为event driven IO(事件驱动IO). 它的好处在于单个进程可以处理多个网络IO请求.select/epoll这两 ...

  8. Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程

    1.使用select模拟socketserver伪并发处理客户端请求,代码如下: import socket import select sk = socket.socket() sk.bind((' ...

  9. I/O多路复用select/poll/epoll

    前言 早期操作系统通常将进程中可创建的线程数限制在一个较低的阈值,大约几百个.因此, 操作系统会提供一些高效的方法来实现多路IO,例如Unix的select和poll.现代操作系统中,线程数已经得到了 ...

随机推荐

  1. web API help pages with Swagger / OpenAPI

    https://docs.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger?view=aspnetc ...

  2. BZOJ:(270,300]

    9/30 BZOJ3038:线段树,不带lazy标记,直接修改叶子. BZOJ3211:同3038 BZOJ1406:将式子转换成[(x-1)*(x+1)%n==0]然后枚举i.当i=x-1时,i*( ...

  3. 对拷 使用scp命令在两台linux上对拷文件或者文件夹

    以前一直是在服务器上tar打包压缩,下载到本地电脑上,再上传到另外一台服务器上,再解压. 其实使用scp命令就可以直接对拷文件或者文件夹了. scp就是secure copy,是用来进行远程文件拷贝的 ...

  4. 使用node-inspector调试NodeJS代码

    使用node-inspector调试NodeJS代码 任何一门完备的语言技术栈都少不了健壮的调试工具,对于NodeJS平台同样如此,笔者研究了几种调试NodeJS代码的方式,通过对比,还是觉得node ...

  5. javascript页面打印

    打印本身比较简单,但要考虑到具体的需求.比如 1. 多浏览器: if (isIE()) { //打印预览 WebBrowser1.execWB(7, 1); } else { window.print ...

  6. 某些编辑器运行C程序闪退的解决办法

    在某些C语言编辑器中运行C语言程序或点击生成的.exe文件出现闪退现象的解决办法,主要有两种,还有其它方法欢迎交流. 包含头文件<windows.h>,在程序末尾添加system(&quo ...

  7. 用Java编程计算出所有的"水仙花数"

    题目:打印出所有的 "水仙花数 ",所谓 "水仙花数 "是指一个三位数,其各位数字立方和等于该数本身.例如:153是一个 "水仙花数 ",因 ...

  8. MFC--根据串口采集的数据借助GDI绘制曲线

    根据采集到的数据绘制曲线 在串口编程中会涉及到这样一个问题,就是将采集到的数据以曲线的形式展示出来,大家自然而然会想到采用方便快捷的控件进行编程.编程周期短,完成任务快,但是真实情况来看,控件会实现很 ...

  9. 在Window工作区按下鼠标左键拖动窗体

    Window.DragMove(): 允许使用在窗口工作区的暴露区域上方按下其鼠标左键的鼠标来拖动窗口.(窗口工作区:除去窗体的title.bottom后的剩余部分空间) 使用该方法时注意:一定要在鼠 ...

  10. iframe框架

    在一个页面里做一个区域引入另一个页面的方法: <a href="http://www.baidu.com" target="in">百度</a ...