poll & epoll & select
来源:互联网 发布:权志龙直播软件 编辑:程序博客网 时间:2024/06/03 17:08
poll,epoll都是常见的多路复用阻塞函数,当然还有select,今天就来学习一下它们是怎么使用的吧。
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#include <poll.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#define MYMOUSE "/dev/hello"#define END "end"#define INFTIM -1static char buf[128];void *poll_thread(void){ int fd = -1; int ret = -1; struct pollfd pollfds[2] = {0}; //监听2路事件,也可以设置更多路 pollfds[0].fd = 0; //0既标准输入,就是键盘 pollfds[0].events = POLLIN; //设置监听输入事件 fd = open(MYMOUSE, O_RDONLY); //自定义的设备节点 pollfds[1].fd = fd; pollfds[1].events = POLLIN; //设置监听输入事件 for(;;) { ret = poll(pollfds, 2, INFTIM); //2表示fd的数量,INFTIM即-1,表示无限阻塞等待,设置大于0表示超时等待,比如3000表示如果3秒内没有事件则自动返回0 if(ret > 0) //大于0表示正常的产生事件 { if(pollfds[0].revents & POLLIN) //判断是否为键盘的输入事件 {memset(buf, 0, sizeof(buf));read(pollfds[0].fd, buf, sizeof(buf)); printf("read for pollfds[0].fd = %s\n", buf); if(strncmp(buf, END, strlen(END)) == 0) //如果输入end结束程序 { printf("thread exit.\n"); break; } } if(pollfds[1].revents & POLLIN) //判断是否为自定义fd的输入事件 {memset(buf, 0, sizeof(buf));read(pollfds[1].fd, buf, sizeof(buf)); printf("read for pollfds[1].fd = %s\n", buf); } } else if(ret == 0) //poll的第三个参数大于0时才有意义,当前设置为-1表示无限等待,是不会返回0的 { perror("poll time out.\n"); break; } else (ret < 0) // 小于0表示出错 { perror("poll"); break; } } return NULL;}
void *epoll_thread(void)
{
int my_fd = -1, epoll_fd = -1;
int ret = -1;
int i = 0;
struct epoll_event event[2], max_event[MAXEVENTS]; //evnet[2]为要监听的两路事件,max_event[MAXEVENTS]表示随时能处理的最大事件数量
epoll_fd = epoll_create(2); // 创建epoll的句柄
if(epoll_fd < 0)
{
perror("epoll_create");
return NULL;
}
event[0].data.fd = 0; //0既标准输入,就是键盘
event[0].events = EPOLLIN | EPOLLET;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 0, &event[0]); //通过EPOLL_CTL_ADD加入对键盘的监听
my_fd = open(MYFD, O_RDONLY); //自定义一个监听
event[1].data.fd = my_fd;
event[1].events = EPOLLIN | EPOLLET;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 0, &event[1]);
for(;;)
{
ret = epoll_wait(epoll_fd, max_event, MAXEVENTS, INFTIM); //阻塞等待事件发生
if(ret > 0)
{
for(i = 0; i < ret; i++)
{
if(max_event[i].data.fd == 0) //判断事件是否来自键盘
{
memset(buf, 0, sizeof(buf));
read(0, buf, sizeof(buf));
printf("read fd0 buf=%s, ret=%d\n", buf, ret);
if(strncmp(buf, END, strlen(END)) == 0)
{
printf("thread exit.\n");
return NULL;
}
}
if(max_event[i].data.fd == my_fd) //判断事件是否来自自定义的fd
{
memset(buf, 0, sizeof(buf));
read(my_fd, buf, sizeof(buf));
printf("read my_fd buf=%s, ret=%d\n", buf, ret);
}
}
}
else if(ret == 0) //epoll_wait最后一个参数为-1,表示无限等待,因此不会超时
{
perror("time out,\n");
}
else
{
perror("error,\n");
}
}
return NULL;
}
void *select_thread(void)
{
int my_fd = -1, ret = -1;
fd_set fd_set1;
FD_ZERO(&fd_set1); //对fd_set清零
FD_SET(0, &fd_set1); //设置对0的监听,0即标准输入,就是键盘
my_fd = open(MYFD, O_RDONLY); //打开一个自定义的句柄
FD_SET(my_fd, &fd_set1); //增添一个自定义的监听
while(1)
{
ret = select(my_fd+1, &fd_set1, NULL, NULL, NULL); //阻塞等待事件发生
if(ret > 0)
{
if (FD_ISSET(0, &fd_set1)) //判断事件是否来自键盘
{
memset(buf, 0, sizeof(buf));
read(0, buf, sizeof(buf));
printf("read fd0 buf=%s\n", buf);
if(strncmp(buf, END, strlen(END)) == 0)
{
printf("thread exit.\n");
break;
}
}
if (FD_ISSET(my_fd, &fd_set1)) //判断是否来自自定义句柄
{
memset(buf, 0, sizeof(buf));
read(my_fd, buf, sizeof(buf));
printf("read my_fd buf=%s\n", buf);
}
}
else if(ret == 0) //select最后一个参数struct timeval*timeout为NULL,表示无限等待,因此不会超时
{
perror("time out select\n");
}
else
{
perror("error select\n");
}
}
return NULL;
}
int main(int argc, char const *argv[]){ int ret = -1; pthread_t pthread_t1; ret = pthread_create(&pthread_t1, NULL, (void *)poll_thread, NULL); //创建线程 if(ret != 0) { perror("pthread_create"); return -1; } ret = pthread_join(pthread_t1, NULL); //等待线程结束 if(ret != 0) { perror("pthread_join error"); } printf("end.\n"); return 0;}
阅读全文
0 0
- select、Poll、epoll比较。
- select,poll,epoll区别
- select,poll,epoll用法
- select, poll, epoll
- select、poll、epoll
- select,poll,epoll区别
- select、poll和epoll
- socket-select ,poll ,epoll
- select poll epoll区别
- select、poll和epoll
- select, poll, epoll
- select,epoll,poll比较
- poll, select, epoll
- select、Poll、epoll比较
- select、poll和epoll
- select,poll,epoll总结
- select,epoll,poll比较
- select,epoll,poll比较
- Ubuntu16.04安装MongoDB Community 和 MongoDB C++ Driver
- python REST Webservice
- 读取properties实现数据库的连接实现类
- c#winform打开指定目录的方法
- JAVA虚拟机栈
- poll & epoll & select
- Hikvision SDK关于JAVA示例的编译及发布
- linux下文件系统
- Android开发:Android Studio工具遇到的坑,以及解决办法
- 分数序列
- 《剑指offer》刷题笔记(数组):二维数组中的查找
- 汇编语言——学习资料(更新........)
- ABAP 友情链接
- css预处理器