linux epoll/select使用区分和实例对比


Linux内核poll,ppoll,epoll,select代码位置:

poll,ppoll,select相关内核实现在在fs/select.c中;

epoll_ctl和epoll_wait相关函数在fs/eventpoll.c中

epoll实测不支持监听普通文件,select可以,但是发现无论是可读、可写,其一直会返回准备就绪状态,所以select也无法实际用来监控普通文件,可用来监听物理设备如uart对应的ttyS0等。

epoll_ctl控制普通文件会返回-1,即EPERM,添加的fd不支持epoll。比如添加的是普通文件描述符内核设备文件poll file operations定义类似如下:

7205909642d848d2977fb361489ab5cb.png

 

如下通过epoll实现监控IO变化:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <signal.h>
#include <semaphore.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <regex.h>
#include <libgen.h>
#include <poll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <stdarg.h>
#include <math.h>
#include <getopt.h>
#include <ctype.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/syscall.h>
#include <sys/eventfd.h>
#include <sys/socket.h>
#include <sys/reboot.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/un.h>
#include <sys/shm.h>
#include <stddef.h>#include <linux/input.h>
#include <linux/types.h>
#include <linux/sockios.h>
#include <linux/ethtool.h>
#include <linux/netlink.h>static bool thread_start = 0;
static int32_t epoll_fd  = -1;
static int32_t g_test_gpio_fd = -1;
static int32_t g_test_status_fd = -1;
static int test_action  = 1;typedef struct{int8_t              thread_name[OWN_THREAD_NAME_SIZE];     //thread namepthread_t     m_thead;                                //thread hanleuint32_t            thread_priority;                        //thread priorityuint32_t            stack_depth;                            //stack sizevoid                *thread_func;                           //thread funcvoid                *para;                                  
}OWN_thread_t;#define OWN_THREAD_NAME_SIZE      20
#define TEST_PATH      "/etc/test_value"
#define OWN_WAKE_GPIO_MAX_SIZE             (10)
#define OWN_MIN_STACK         100*1024
#define F_FAIL -1
#define F_SUCCESS 1
#define EPOLL_LISTEN_TIMEOUT                (1000)
#define OWN_BUFSIZE_4                  4
#define OWN_THREAD_PRIORITY            3
#define OWN_test_THREAD_STACK_SIZE       (16 * 1024)//byte(16kb)int32_t OWN_thread_create(OWN_thread_t *threadin)
{int32_t ret = -1;if(threadin == NULL){printf("threadin is null\n");}pthread_attr_t attr;ret = pthread_attr_init(&attr);if (ret != 0){printf("pthread_attr_init Error\n");return -1;}if(threadin->stack_depth < OWN_MIN_STACK){threadin->stack_depth = OWN_MIN_STACK;}ret = pthread_attr_setstacksize(&attr, threadin->stack_depth);if(ret != 0){printf("pthread_attr_setstacksize %d Error=%d\n",threadin->stack_depth,ret);return -1;}ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);if(ret != 0){printf("pthread_attr_setdetachstate Error=%d\n",ret);return -1;}ret = pthread_create(&(threadin->m_thead), &attr, threadin->thread_func, (void *)(threadin->para));pthread_attr_destroy (&attr);if(ret != 0){printf("pthread_create Error, ret=%d, err:%s\n", ret, strerror(errno));return F_FAIL;}else{return F_SUCCESS;}return F_FAIL;
}static void *OWN_thread_wake_gpio_monitor_handler(void *arg)
{static int32_t first_reload = 1;int32_t fd_cnt = 0;int32_t ret = 0;int32_t i = 0;int8_t value[OWN_BUFSIZE_4] = {0};struct epoll_event events[OWN_WAKE_GPIO_MAX_SIZE];int8_t value_status = 0;while (thread_start){memset(events, 0x0, sizeof(events));fd_cnt = epoll_wait(epoll_fd, events, OWN_WAKE_GPIO_MAX_SIZE, EPOLL_LISTEN_TIMEOUT);if(fd_cnt <= 0){continue;}for(i = 0; i < fd_cnt; i++){memset(value, 0x0, sizeof(value));lseek(events[i].data.fd, 0, SEEK_SET);ret = read(events[i].data.fd, value, sizeof(value));value_status = atoi((const char *)value);printf("value =%s value_status =%d ret : %d\n", value, value_status, ret);if (events[i].events & EPOLLPRI  && events[i].data.fd == g_test_gpio_fd){printf("gpio test file \r\n");if (test_action != NULL){printf("callback test value =%s value_status =%d ret : %d\n", value, value_status, ret);}}}}return NULL;
}int main()
{int ret = 0;struct epoll_event evd = {0};OWN_thread_t test_gpio_thread;epoll_fd = epoll_create(OWN_WAKE_GPIO_MAX_SIZE);if (epoll_fd < 0){printf("epoll error \n");}g_test_gpio_fd = open(TEST_PATH , O_RDONLY | O_NONBLOCK);if (g_test_gpio_fd < 0){printf("open error \n");}memset(&evd, 0x0, sizeof(evd));evd.data.fd = g_test_gpio_fd;evd.events = EPOLLPRI;ret = epoll_ctl(g_test_epoll_fd, EPOLL_CTL_ADD, epoll_fd, &evd);if (ret < 0){printf("epoll_ctl error \n");}thread_start = 1;memset(&test_gpio_thread, 0, sizeof(test_gpio_thread));snprintf((char*)test_gpio_thread.thread_name,OWN_THREAD_NAME_SIZE - 1, "Notify handle");test_gpio_thread.thread_priority  = OWN_THREAD_PRIORITY;test_gpio_thread.stack_depth      = OWN_test_THREAD_STACK_SIZE;test_gpio_thread.thread_func      = OWN_thread_wake_gpio_monitor_handler;test_gpio_thread.para             = NULL;ret = OWN_thread_create(&test_gpio_thread);if (ret != F_SUCCESS) {printf("OWN_thread_wake_gpio_monitor_handler creation failure !\n");}while(1){sleep(2);}return 0;
}

select应用示例:如下实例为监听普通文件,发现返回值一直大于0,监听意义不大。可以将监听的设备改为ttyS0,则可以正常监控。

函数返回值如下:

>0:就绪描述字的正数目

-1:出错

0 :超时

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <signal.h>
#include <semaphore.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <regex.h>
#include <libgen.h>
#include <poll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <stdarg.h>
#include <math.h>
#include <getopt.h>
#include <ctype.h>#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/syscall.h>
#include <sys/eventfd.h>
#include <sys/socket.h>
#include <sys/reboot.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/un.h>
#include <sys/shm.h>
#include <stddef.h>
#include <linux/input.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <linux/sockios.h>
#include <linux/ethtool.h>
#include <linux/netlink.h>static pthread_t test_thread;
int fd = 0;
static void *thread_func(void * arg);int main(int argc, char * argv [ ])
{int ret;char buf[] = "hello test! ";if (argc < 2){return -1;}setbuf(stdout, NULL);fd = open("/etc_rw/test_select", O_RDWR  | O_NONBLOCK);if (fd > 0){printf("Open success! \n");}else{printf("Open failure! \n");}if (pthread_create(&test_thread, NULL, thread_func, NULL) != 0){printf("Failed to creat thread \n");}while (fd >= 0){//ret = write(fd, (uint8_t*)buf, strlen(buf));printf("Write fd value = %d, ret value = %d \n", fd, ret);sleep(2);}return 0;
}static void *thread_func(void * arg)
{int ret;fd_set fdset;struct timeval timeout = {4, 0};char buf[100] = {0};timeout.tv_sec = 5;timeout.tv_usec = 0;while (fd >= 0){FD_ZERO(&fdset);FD_SET(fd, &fdset);ret = select(fd + 1, &fdset, NULL, NULL, &timeout);if (ret == -1){printf("Failed to select \n");}else if (ret == 0){printf("ret value is 0 \n");timeout.tv_sec = 4;timeout.tv_usec = 0;}else{if (FD_ISSET(fd, &fdset)){//do// {memset(buf, 0, 100);ret = read(fd, buf, 100);printf("Read ret = %d buf = %s \n", ret, buf);// }while(ret == 200);}}}return (void *)1;
}


 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/8614.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Python+MySQL所写的医院管理系统

点击以下链接获取源码资源&#xff1a; https://download.csdn.net/download/qq_64505944/87985429?spm1001.2014.3001.5503 目录 摘要 I 1 需求分析 1 1.1 任务描述 1 1.2 需求分析的过程 1 1.3 业务需求 2 1.4 功能描述 2 2 总体设计 3 2.1 系统开发环境 3 2.2 系统功能流…

26488-24-4,Cyclo(D-Phe-L-Pro),具有良好的生物相容性

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ 【产品描述】 Cyclo(D-Phe-L-Pro)环(D-苯丙氨酸-L-脯氨酸)&#xff0c;环二肽是由两个氨基酸通过肽键环合形成&#xff0c;是自然界中小的环状肽。由于其存在两个酰胺键即四个可以形成氢键的位点&#xff0c;环二肽可以在氢…

系统没有“internet信息服务(IIS)管理器”

系统没有“internet信息服务&#xff08;IIS&#xff09;管理器” 解决方案1.打开控制面板&#xff0c;找到并打开程序。2.找到并打开程序里的启用或关闭windows功能。3.在‘Internet Information Services’下的‘web管理工具’中找到IIS相关功能&#xff0c;在前面的复选框中…

Java Spring多线程

Java Spring多线程 开启一个线程1 继承java.lang.Thread类2 实现java.lang.Runnable接口3 实现Callable接口4 实现线程池ThreadPoolExecutor 操作线程线程的状态1 等待线程 join()2 中断线程 interrupt()3 守护线程&#xff08;Daemon Thread&#xff09; Java线程池Executors …

pinia状态管理

1.pinia是什么&#xff1f; 官网解释&#xff1a; Pinia 是 Vue 的存储库&#xff0c;它允许您跨组件/页面共享状态。 2.为什么要使用pinia&#xff1f; 优点&#xff1a; Vue2和Vue3都支持&#xff0c;这让我们同时使用Vue2和Vue3的小伙伴都能很快上手。pinia中只有state、…

MySQL:七种 SQL JOINS 的实现(图文详解)

MySQL&#xff1a;7种SQL JOINS的实现 前言一、图示表示二、代码举例1、INNER JOIN&#xff08;内连接&#xff09;2、LEFT JOIN&#xff08;左连接&#xff09;3、RIGHT JOIN&#xff08;右连接&#xff09;4、OUTER JOIN&#xff08;全连接&#xff09;5、LEFT EXCLUDING JOI…

Android Studio 下载安装教程

在我们下载前&#xff0c;先来了解一下Android的4大组件&#xff1a; 1.活动 2.服务&#xff1a;类似线程&#xff0c;听歌时跳转发信息&#xff0c;后台进行播放音乐&#xff0c;前台交互&#xff0c;后台运行任务 3.广播接收者&#xff1a;【例1】感知充电线充电进度&#xf…

Mac 配置Flutter开发环境遇到的坑

1. flutter doctor 命令无反应; 加sudo 执行; sudo flutter doctor执行完后, 在执行flutter doctor就好使了, 就很神奇;(还不行就重启再试试) 2. 创建项目提示没权限, 照提示命令赋予权限即可;(应该是前面sudo命令引起的, 但没找到其他好办法) 最后一个提示的没权限, 照提示运…

MYSQL的基础架构

了解MySQL&#xff08;超详细的MySQL工作原理 体系结构&#xff09; 1.MySQL体系结构 2.MySQL内存结构 3.MySQL文件结构 4.innodb体系结构 一、了解MySQL前你需要知道的 引擎是什么: MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同…

Spring源码解析(一):环境搭建

Spring源码系列文章 Spring源码解析(一)&#xff1a;环境搭建 目录 一、Spring源码基础组件1、bean定义接口体系2、bean工厂接口体系3、ApplicationContext上下文体系 二、测试环境准备 一、Spring源码基础组件 阅读源码时候&#xff0c;接口与类过多&#xff0c;可以对照这里…

Could not load the Qt platform plugin “xcb“

qt.core.plugin.loader: QLibraryPrivate::loadPlugin failed on “/home/ly/Qt/6.5.1/gcc_64/plugins/platforms/libqxcb.so” : “Cannot load library /home/ly/Qt/6.5.1/gcc_64/plugins/platforms/libqxcb.so: (libxcb-cursor.so.0: cannot open shared object file: No su…

了解Java可见性的本质

作者&#xff1a;早恒 前一段时间重温了伪共享&#xff08;false sharing&#xff09;问题&#xff0c;了解到深处有几个问题一直想不明白&#xff0c;加上开发过程中遇到volatile时总觉得理解不够透彻&#xff0c;借着这次脑子里这几个问题&#xff0c;探究下Java可见性的本质…