SylixOS 之epoll异常分析
admin
2023-03-16 06:21:01
0次

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 
#include 
#include 
#include 
#include 
#include 
#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所示。

SylixOS 之epoll异常分析

 

图 2-1 运行结果

    此时线程test_wait阻塞等待事件产生,根据程序清单 2-1所示,send_data线程一直在写入数据,同时test_ctl线程也在把事件加入epoll中监听。

2.2epoll异常分析

    SylixOS epoll兼容子系统是由select子系统模拟出来的,分析epoll_wait源码。epoll_wait代码框架如图 2-2所示。

SylixOS 之epoll异常分析 

图 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所示。

SylixOS 之epoll异常分析 

图 3-1 运行结果

    在SylixOS上使用epoll功能需要注意要保证epoll_wait在epoll_ctl设置之后使用,这样保证epoll_wait监听的文件描述符集合不为空。

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...