博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poll
阅读量:6452 次
发布时间:2019-06-23

本文共 4559 字,大约阅读时间需要 15 分钟。

  poll, ppoll - wait for some event on a file descriptor

  man page: 

 

  poll 是一种多路复用的IO机制。使用 poll 可以监听多个文件描述符,一但某个文件描述符就绪(一般是读就绪或者写就绪),能够通知程序进行响应的读写操作。

  poll 本质是一种同步IO,因为需要在读写事件就绪后自己负责读写,也就是说这个读写过程是阻塞的,而异步IO则无需自己负责读写,异步IO的实现会负责把数据从内核拷贝到用户空间。

#include 
int poll(struct pollfd *fds, nfds_t nfds, int timeout);/** * 由于 poll 是监听多个文件描述符,所以 fds 传递的是数组地址 * nfds 指定监听的文件描述符个数 * timeout 超时时间,单位是 milliseconds * * 因为 poll 是同步 IO,那么 poll 必然是带阻塞的,带阻塞的函数,必然要设置超时时间,防止死等却等不到的情况。 */

 

struct pollfd {    int   fd;         /* file descriptor */    short events;     /* requested events */    short revents;    /* returned events */};/** * fd     : 是要监听的文件描述符 * events : 要监听的事件 * revents: 实际发生的事件 */

  pollfd 没有最大数量的限制,但是数量过大后性能会下降。当然,随着pollfd的个数增加,poll 函数返回后,用户继续遍历 poll 数组也会更加耗时。

/* 常用参数说明 */       POLLIN There is data to read.       POLLPRI              There is some exceptional condition on the file descriptor.              Possibilities include:              *  There is out-of-band data on a TCP socket (see tcp(7)).              *  A pseudoterminal master in packet mode has seen a state                 change on the slave (see ioctl_tty(2)).              *  A cgroup.events file has been modified (see cgroups(7)).       POLLOUT              Writing is now possible, though a write larger that the avail‐              able space in a socket or pipe will still block (unless O_NON‐              BLOCK is set).       POLLRDHUP (since Linux 2.6.17)              Stream socket peer closed connection, or shut down writing              half of connection.  The _GNU_SOURCE feature test macro must              be defined (before including any header files) in order to              obtain this definition.       POLLERR              Error condition (only returned in revents; ignored in events).              This bit is also set for a file descriptor referring to the              write end of a pipe when the read end has been closed.       POLLHUP              Hang up (only returned in revents; ignored in events).  Note              that when reading from a channel such as a pipe or a stream              socket, this event merely indicates that the peer closed its              end of the channel.  Subsequent reads from the channel will              return 0 (end of file) only after all outstanding data in the              channel has been consumed.       POLLNVAL              Invalid request: fd not open (only returned in revents;              ignored in events).       When compiling with _XOPEN_SOURCE defined, one also has the follow‐       ing, which convey no further information beyond the bits listed       above:       POLLRDNORM              Equivalent to POLLIN.       POLLRDBAND              Priority band data can be read (generally unused on Linux).       POLLWRNORM              Equivalent to POLLOUT.       POLLWRBAND              Priority data may be written.       Linux also knows about, but does not use POLLMSG.

   可以对照英文和中文翻译进行深入理解:

   不难理解,再贴一个示例demo:

#include 
#include
#include
#include
#include
#include
#include
#include
#define W_DATA "howaylee"int main(int argc, char* argv[]){ int ret = -1; int fd1 = -1; int fd2 = -1; char r_buf[12] = { 0}; struct pollfd fds[2] = { 0}; // open fd1 fd1 = open(argv[1], O_RDWR|O_CREAT, S_IRWXU); if (-1 == fd1) { perror("open fd1 failed: "); return -1; } // write fd1 ret = write(fd1, W_DATA, sizeof(W_DATA)); if (-1 == ret) { perror("write fd1 failed: "); goto _OUT; } // lseek fd1 head ret = lseek(fd1, 0, SEEK_SET); if (-1 == ret) { perror("lseek fd1 failed: "); goto _OUT; } // open fd2 fd2 = open(argv[2], O_RDWR|O_CREAT, S_IRWXU); if (-1 == fd2) { perror("open fd2 failed: "); return -1; } /* 阻塞,等待程序读写操作 */ while (1) { // 初始化 pollfd fds[0].fd = fd1; // 可读 fds[0].events = POLLIN; fds[1].fd = fd2; // 可写 fds[1].events = POLLOUT; // poll ret = poll(fds, sizeof(fds)/sizeof(fds[0]), -1); if (-1 == ret) { perror("poll failed: "); goto _OUT; } // read fd1 if (fds[0].revents & POLLIN) { // 清空缓存 memset(r_buf, 0, sizeof(r_buf)); ret = read(fd1, r_buf, sizeof(r_buf)); if (-1 == ret) { perror("poll read failed: "); goto _OUT; } // printf("read = %s\n", r_buf); } // write fd2 if (fds[1].revents & POLLOUT) { ret = write(fd2, r_buf, sizeof(r_buf)); if (-1 == ret) { perror("poll write failed: "); goto _OUT; } printf("write = %s\n", r_buf); } } //close fd1 fd2 close(fd1); close(fd2); _OUT: return ret;}

 

 

 

 

asdf 

转载于:https://www.cnblogs.com/ronny-blog/p/8260251.html

你可能感兴趣的文章
c/c++通用内存泄漏检测框架GMFD(General Memory Fault Detection Framework)
查看>>
异构计算:PC的“动车组”
查看>>
MariaDB 10之TokuDB存储引擎
查看>>
Flex与.NET互操作(一):基于Socket的网络连接
查看>>
WPF中Style的使用
查看>>
组策略设置服务器安全-----不显示最后的用户名
查看>>
慢查询日志的另外一种方法
查看>>
引发CPU占用率快100%的可能原因
查看>>
公司今年的一道校招笔试题--五猴分桃
查看>>
[数据恢复答疑]RAID5有一块硬盘离线后,为什么不建议马上做REBUILD?
查看>>
Exchange 2013 EAC之管理员重置普通用户密码
查看>>
三线跑酷例子BlocksRun的技术点
查看>>
如何应对DDOS网络攻击
查看>>
新闻奖颁给了一个写稿机器人(来自新华社)
查看>>
Android应用程序在新的进程中启动新的Activity的方法和过程分析
查看>>
顺序表的算法
查看>>
由system.currentTimeMillis() 获得当前的时间
查看>>
Android 2.1 源码结构分析
查看>>
android 缓存管理的方法
查看>>
tmp目录自动清除和tmpwatch命令
查看>>