SylixOS 之epoll异常分析

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           7
int     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监听的文件描述符集合不为空。

时间: 2024-10-26 05:28:06

SylixOS 之epoll异常分析的相关文章

MySQL 外键异常分析

外键约束异常现象 如下测例中,没有违反引用约束的插入失败. create database `a-b`; use `a-b`; SET FOREIGN_KEY_CHECKS=0; create table t1(c1 int primary key, c2 int) engine=innodb; create table t2(c1 int primary key, c2 int) engine=innodb; alter table t2 add foreign key(c2) referen

Android异常分析(转)

关于异常 异常? 异常就是一种程序中没有预料到的问题,既然是没有预料到的,就可能不在原有逻辑处理范围内,脱离了代码控制,软件可能会出现各种奇怪的现象.比如:android系统常见异常现象有应用无响应.应用停止运行.冻屏.重启.死机等,这些异常系统有统一的异常处理机制,出现异常系统就会执行相应的操作,最终有相应的现象体现出来.另外,一些不在预料之中的界面显示问题,操作问题,运行卡顿问题等也可以归于异常,只不过这种异常是人为逻辑缺陷,对系统来说是正常的,但这些缺陷在异常现象中占比却相当大,直接体现出

poll&amp;&amp;epoll实现分析(二)——epoll实现

Epoll实现分析--作者:lvyilong316 通过上一章分析,poll运行效率的两个瓶颈已经找出,现在的问题是怎么改进.首先,如果要监听1000个fd,每次poll都要把1000个fd 拷入内核,太不科学了,内核干嘛不自己保存已经拷入的fd呢?答对了,epoll就是自己保存拷入的fd,它的API就已经说明了这一点--不是 epoll_wait的时候才传入fd,而是通过epoll_ctl把所有fd传入内核再一起"wait",这就省掉了不必要的重复拷贝.其次,在 epoll_wait

poll&amp;&amp;epoll实现分析(一)——poll实现

0.等待队列 在Linux内核中等待队列有很多用途,可用于中断处理.进程同步及定时.我们在这里只说,进程经常必须等待某些事件的发生.等待队列实现了在事件上的条件等待: 希望等待特定事件的进程把自己放进合适的等待队列,并放弃控制全.因此,等待队列表示一组睡眠的进程,当某一条件为真时,由内核唤醒它们. 等待队列由循环链表实现,由等待队列头(wait_queue_head_t)和等待队列项(wait_queue)组成,其元素(等待队列项)包含指向进程描述符的指针.每个等待队列都有一个等待队列头(wai

Java ConcurrentModificationException 异常分析与解决方案

Java ConcurrentModificationException 异常分析与解决方案http://www.2cto.com/kf/201403/286536.html java.util.ConcurrentModificationException 解决办法 http://blog.csdn.net/lipei1220/article/details/9028669 原因:Iterator做遍历的时候,HashMap被修改(bb.remove(ele), size-1),Iterato

java.net.SocketException:Software caused connection abort: recv failed 异常分析 +socket客户端&amp;服务端代码

java.net.SocketException:Software caused connection abort: recv failed 异常分析 分类: 很多的技术 2012-01-04 12:54 8004人阅读 评论(6) 收藏 举报 socket服务器bufferstring网络java 第 1个异常是java.net.BindException:Address already in use: JVM_Bind.该异常发生在服务器端进行new ServerSocket(port)(p

log4j-over-slf4j与slf4j-log4j12共存stack overflow异常分析

注:下文中的"桥接"."转调"."绑定"等词基本都是同一个概念. log4j-over-slf4j和slf4j-log4j12是跟java日志系统相关的两个jar包,当它们同时出现在classpath下时,就可能会引起堆栈溢出异常.异常信息大致如下(摘自slf4j官网文档Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting St

理解select,poll,epoll实现分析

mark 引用:http://janfan.cn/chinese/2015/01/05/select-poll-impl-inside-the-kernel.html 文章 select()/poll() 的内核实现 05 Jan 2015 同时对多个文件设备进行I/O事件监听的时候(I/O multiplexing),我们经常会用到系统调用函数select() poll(),甚至是为大规模成百上千个文件设备进行并发读写而设计的epoll(). I/O multiplexing: When an

常? OOM 异常分析

---------作者: 捡?螺的?男孩 常? OOM 异常分析 堆溢出 栈溢出 方法区溢出 本机直接内存溢出 GC overhead limit exceeded 一.堆溢出 Java 堆?于存储对象实例,只要不断地创建对象,并且保证 GC Roots 到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么 在对象数量到达最?堆的容量限制后就会产?内存溢出异常. 原因 无法在java堆中分配对象 应用程序保存了无法被GC回收的对象 应用程序过度使用finalizer 排查解决思路 查找关键报