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!\n");
 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.\n");
 48         return 0;
 49     }
 50     
 51     iEvtfd1 = eventfd(0,EFD_SEMAPHORE);
 52     if (-1 == iEvtfd1)
 53     {
 54         printf("failed to create eventfd1\n");
 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\n");
 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\n");
 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\n");
 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.\n", iRet);
110             if(stEpEvent.data.fd == g_iEvtfd1)
111             {
112                 printf("g_iEvtfd1 event\n"); 
113                 s = eventfd_read(g_iEvtfd1, &uiRead);
114                 if (s != 0)
115                 {
116                     printf("read g_iEvtfd1 failed\n");
117                     break;
118                 }
119                 printf("Read %llu (0x%llx) from g_iEvtfd1\n", uiRead, uiRead);                
120             }
121             else if (stEpEvent.data.fd == g_iEvtfd2)
122             {
123                 printf("g_iEvtfd2 evnet\n");
124                 s = eventfd_read(g_iEvtfd2, &uiRead);
125                 if (s != 0)
126                 {
127                     printf("read g_iEvtfd2 failed\n");
128                     break;
129                 }
130                 printf("Read %llu (0x%llx) from g_iEvtfd2\n", 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

 

posted @ 2016-04-07 15:14  kane_zch  阅读(1106)  评论(0编辑  收藏  举报