SylixOS 之epoll异常分析
来源:互联网 发布:网络赌钱平台怎么做 编辑:程序博客网 时间:2024/06/06 02:39
1. SylixOS epoll介绍
SylixOS为了兼容Linux的epoll,创建了epoll的兼容子系统,并支持了epoll的部分功能。SylixOS epoll兼容子系统是由select子系统模拟出来的,所以效率没有select高。
2. epoll异常分析
2.1epoll异常场景
在使用线程A创建AF_UNIX匿名套接字发送数据;线程B把套接字加入epoll监听,且设置属性为一次有效;线程C等待epoll事件产生,并读取套接字中的数据。如程序清单 2-1所示。
程序清单 2-1
#include <stdio.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <pthread.h>#include <sys/epoll.h>#define READSIZE 7int iEfd = 0;int iFd[2] = {0};void *send_data (void *arg){ int iRet = 0; /* * 使用socketpair函数创造一对未命名的、相互连接的UNIX域套接字 * 并且的在一端不断的发送数据 */ iRet = socketpair(AF_UNIX, SOCK_STREAM, 0, iFd); if (iRet < 0) { perror("socketpair"); return NULL; } for (;;) { write(iFd[0], "SylixOS", READSIZE); sleep(1); }}void *test_ctl(void *arg){ struct epoll_event event; int iRet = 0; while (1) { / * * 把套接字加入epoll监听,且设置监听属性为一次有效 */ event.events = 0; event.events = EPOLLIN | EPOLLONESHOT; event.data.fd = iFd[1]; iRet = epoll_ctl(iEfd, EPOLL_CTL_MOD, iFd[1], &event); if (iRet == 0) { printf("test_ctl ctl ok\n"); } sleep(1); }}void *test_wait(void *arg){ struct epoll_event event; int iRet = 0; char cBuf[READSIZE] = {0}; while (1) { / * * 使用epoll等待事件,并读取数据。读取结束后等待下一次事件产生 */ iRet = epoll_wait(iEfd, &event, 1, -1); if (iRet == 1) { printf("test_wait event.data.fd is %d event.events is %x\n", event.data.fd,event.events); read(iFd[1], cBuf, READSIZE); } sleep(1); }}int main(int argc, char **argv){ pthread_t send_tid, wait_tid, ctl_tid; int iRet = 0; struct epoll_event event; /* * 创建一个 epoll 文件描述符 */ iEfd = epoll_create(10); if (0 == iEfd) { perror("epoll create"); return (-1); } iRet = pthread_create(&send_tid, NULL, &send_data, NULL); if (iRet != 0) { fprintf(stderr, "pthread create failed.\n"); return (-1); } sleep(1); / * * 把套接字加入epoll监听,且设置为一次有效 */ event.events = EPOLLIN | EPOLLONESHOT; event.data.fd = iFd[1]; iRet = epoll_ctl(iEfd, EPOLL_CTL_ADD, iFd[1], &event); if (iRet != 0) { perror("epoll_ctl"); return (-1); } iRet = pthread_create(&wait_tid, NULL, &test_wait, NULL); if (iRet != 0) { perror("pthread create"); return (-1); } iRet = pthread_create(&ctl_tid, NULL, &test_ctl, NULL); if (iRet != 0) { perror("pthread create"); return (-1); } pthread_join(send_tid, NULL); pthread_join(wait_tid, NULL); pthread_join(ctl_tid, NULL); return (0);}
该程序运行时,运行结果如图 2-1所示。
图 2-1 运行结果
此时线程test_wait阻塞等待事件产生,根据程序清单 2-1所示,send_data线程一直在写入数据,同时test_ctl线程也在把事件加入epoll中监听。
2.2epoll异常分析
SylixOS epoll兼容子系统是由select子系统模拟出来的,分析epoll_wait源码。epoll_wait代码框架如图 2-2所示。
图 2-2 epoll_wait流程
根据epoll_wait实现流程可以发现,如果在epoll_ctl设置事件属性为一次有效,在epoll_wait后事件属性置空。如果此刻epoll_wait在下次epoll_ctl操作之前使用,那么epoll_wait中监听的文件描述符集合即为空(因为事件属性为空),所以select一直处于监听,且没有事件产生。
3. epoll异常总结
把程序清单 2-1中设置保证epoll_wait在epoll_ctl之后运行,运行结果如图 3-1所示。
图 3-1 运行结果
在SylixOS上使用epoll功能需要注意要保证epoll_wait在epoll_ctl设置之后使用,这样保证epoll_wait监听的文件描述符集合不为空。
- SylixOS 之epoll异常分析
- SylixOS Makefile分析
- SylixOS启动脚本分析
- SylixOS高精度时钟分析
- epoll之ep_insert()源码分析
- SylixOS之glib移植
- SylixOS之TFTP使用
- SylixOS周期定时抖动分析
- Linux之epoll族实现分析
- 基于SylixOS的Telnet退出异常
- epoll分析
- epoll 分析
- SylixOS 网卡驱动netdev_notify函数分析
- SylixOS中AHCI驱动框架分析
- SylixOS热插拔子系统分析(二)
- SylixOS线程创建的流程分析
- SylixOS CAN总线驱动之二
- SylixOS CAN总线驱动之三
- 插入数据时返回主键
- 深度学习DeepLearning.ai系列课程学习总结:10. 初始化、正则化、梯度检查实战
- 剑指Offer--9.变态跳台阶
- 直观理解机器学习中的偏差和方差
- Java笔记之final修饰符
- SylixOS 之epoll异常分析
- mui中table的假分页
- js360导航拖住效果~
- 深度学习DeepLearning.ai系列课程学习总结:12. 优化算法实战
- Java总结篇系列:Java泛型
- 关于异常处理的解决方案
- 作业5
- 软件工程作业
- 输入n个元素组成的序列S,你需要找出一个乘积最大的连续子序列。如果这个最大的乘积不是正数,应输出0(表示无解)。1<=18,-10<=Si<=10