zoukankan      html  css  js  c++  java
  • epoll监听多文件描述符时调度顺序研究

    当Epoll监听多个FD时,一直很好奇如果多个FD同时有事件触发,它是如何来进行调度的,调度的顺序是否和事件触发的顺序有关系?
    借助简单的代码来分析一下:

    代码原理较简单:
    1. 主线程中创建两个eventfd描述符,加入epoll
    2. 主线程在epoll_wait前,先在子线程中循环写入10次,调eventfd_write
    3. 主线程进入epoll_wait,进行事件调度,读eventfd

    结论:与调度顺序没有关系,结果可以看到fd1和fd2的事件是交替被处理到的

      1 #include <sys/eventfd.h>
      2 #include <unistd.h>
      3 #include <stdlib.h>
      4 #include <stdio.h>
      5 #include <stdint.h>  
      6 #include <sys/epoll.h>  
      7 #include <string.h>  
      8 #include <pthread.h>  
      9 
     10 int g_iEvtfd1 = -1;
     11 int g_iEvtfd2 = -1;
     12 
     13 void *eventfd_child_Task(void *pArg)
     14 {
     15     uint64_t uiWrite = 1;
     16     int i = 0;
     17 
     18     for(i=0;i<10;i++)
     19     {
     20         eventfd_write(g_iEvtfd1, uiWrite);
     21     }
     22 
     23     for(i=0;i<10;i++)
     24     {
     25         eventfd_write(g_iEvtfd2, uiWrite);
     26     }
     27     
     28     printf("The child task is done!
    ");
     29     return;
     30 }
     31 
     32 int main(int argc, char**argv[])
     33 {
     34     int iEvtfd1, iEvtfd2, j;
     35     uint64_t uiWrite = 1;
     36     uint64_t uiRead;
     37     ssize_t s;
     38     int iEpfd;
     39     struct epoll_event stEvent;
     40     int iRet = 0;
     41     struct epoll_event stEpEvent;
     42     pthread_t stWthread;
     43     
     44     iEpfd = epoll_create(1);
     45     if (-1 == iEpfd)
     46     {
     47         printf("Create epoll failed.
    ");
     48         return 0;
     49     }
     50     
     51     iEvtfd1 = eventfd(0,EFD_SEMAPHORE);
     52     if (-1 == iEvtfd1)
     53     {
     54         printf("failed to create eventfd1
    ");
     55         return 0;
     56     }
     57     g_iEvtfd1 = iEvtfd1;
     58     
     59     iEvtfd2 = eventfd(0,EFD_SEMAPHORE);
     60     if (-1 == iEvtfd2)
     61     {
     62         printf("failed to create eventfd2
    ");
     63         return 0;
     64     }    
     65     
     66     g_iEvtfd2 = iEvtfd2;
     67     
     68     memset(&stEvent, 0, sizeof(struct epoll_event));
     69     stEvent.events = (unsigned long) EPOLLIN;
     70     stEvent.data.fd = g_iEvtfd1;
     71     iRet = epoll_ctl(iEpfd, EPOLL_CTL_ADD, g_iEvtfd1, &stEvent);
     72     if (0 != iRet)
     73     {
     74         printf("failed to add g_iEvtfd1 to epoll
    ");
     75         close(g_iEvtfd1);
     76         close(g_iEvtfd2);
     77         close(iEpfd);
     78         return 0;
     79     }
     80     
     81     memset(&stEvent, 0, sizeof(struct epoll_event));
     82     stEvent.events = (unsigned long) EPOLLIN;
     83     stEvent.data.fd = g_iEvtfd2;
     84     iRet = epoll_ctl(iEpfd, EPOLL_CTL_ADD, g_iEvtfd2, &stEvent);
     85     if (0 != iRet)
     86     {
     87         printf("failed to add g_iEvtfd2 to epoll
    ");
     88         close(g_iEvtfd1);
     89         close(g_iEvtfd2);
     90         close(iEpfd);
     91         return 0;
     92     }
     93     
     94     iRet = pthread_create(&stWthread, NULL, eventfd_child_Task, NULL);
     95     if (0 != iRet)
     96     {
     97         close(g_iEvtfd1);
     98         close(g_iEvtfd2);
     99         close(iEpfd);
    100         return;
    101     }
    102     
    103     for(;;)
    104     {
    105         sleep(2);
    106         iRet = epoll_wait(iEpfd, &stEpEvent, 1, -1);
    107         if (iRet > 0)
    108         {
    109             printf("epoll_wait return %d.
    ", iRet);
    110             if(stEpEvent.data.fd == g_iEvtfd1)
    111             {
    112                 printf("g_iEvtfd1 event
    "); 
    113                 s = eventfd_read(g_iEvtfd1, &uiRead);
    114                 if (s != 0)
    115                 {
    116                     printf("read g_iEvtfd1 failed
    ");
    117                     break;
    118                 }
    119                 printf("Read %llu (0x%llx) from g_iEvtfd1
    ", uiRead, uiRead);                
    120             }
    121             else if (stEpEvent.data.fd == g_iEvtfd2)
    122             {
    123                 printf("g_iEvtfd2 evnet
    ");
    124                 s = eventfd_read(g_iEvtfd2, &uiRead);
    125                 if (s != 0)
    126                 {
    127                     printf("read g_iEvtfd2 failed
    ");
    128                     break;
    129                 }
    130                 printf("Read %llu (0x%llx) from g_iEvtfd2
    ", uiRead, uiRead);                    
    131             }
    132             else{
    133                 printf("epoll wait error!");
    134             }
    135         }
    136     }
    137     
    138     close(g_iEvtfd1);
    139     close(g_iEvtfd2);
    140     close(iEpfd);
    141     return 0;
    142 }
    epoll_schedulemultifd
  • 相关阅读:
    win10 开机背景图
    关于在不知道具体实例化哪个窗体时调用该窗体公共变量的方法
    devexpress 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 “lc.exe”已退出,代码为 -1。
    获取打印机设置的纸张参数
    mysql 添加字段语句
    curl模拟post请求
    php CI框架log写入
    winform程序更新
    JSP的EL和JSTL解析
    报错:java.lang.IllegalArgumentException: object is not an instance of declaring class
  • 原文地址:https://www.cnblogs.com/zhengchunhao/p/5363743.html
Copyright © 2011-2022 走看看