码迷,mamicode.com
首页 > 其他好文 > 详细

游戏服务器学习进度之epoll

时间:2014-10-19 15:37:29      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   os   ar   for   sp   文件   

epoll是Linux内核为处理大批句柄而作改进的poll,是Linux下多路复用IO接口 select/poll的增强版本,它能显著的减少程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。因为它会复用文件描述符集合来传递结果 而不是迫使开发者每次等待事件之前都必须重新准备要被侦听的文件描述符集合,另一个原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那 些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select\poll那种IO事件的电平触发(Level Triggered)外,还提供了边沿触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提供应用程序的效率

简单写了一个范例:

  1 #include <stdio.h>
  2 #include <sys/types.h>
  3 #include <sys/socket.h>
  4 #include <netinet/in.h>
  5 #include <arpa/inet.h>
  6 #include <sys/epoll.h>
  7 #include <fcntl.h>
  8 #include <errno.h>
  9 #include <unistd.h>
 10 
 11 
 12 #define BUF_SIZE 1024
 13 #define EPOLL_SIZE 10000
 14 
 15 //设置socket为非阻塞模式
 16 int setnonblocking(int fd)
 17 {
 18     int ret;
 19     ret = fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
 20     if(ret < 0)
 21     {
 22         perror("set nonbock failed\n");
 23         return -1;
 24     }
 25 
 26     return 0;
 27 }
 28 
 29 //网络消息处理
 30 int handle_message(int fd)
 31 {
 32 
 33 }
 34 
 35 int main(int argc, char** argv)
 36 {
 37     if(argc != 2)
 38     {
 39         perror("Usage: port\n\n");
 40         return 1;
 41     }
 42 
 43     int listener;
 44     int ret;
 45     int port;
 46     port = atoi(argv[1]);
 47 
 48     
 49     struct sockaddr_in addr, their_addr;
 50     addr.sin_family = AF_INET;
 51     addr.sin_port = htons(port);
 52     addr.sin_addr.s_addr = htonl(INADDR_ANY);
 53 
 54     socklen_t socklen;
 55     socklen = sizeof(struct sockaddr_in);
 56   //epoll事件结构体 
 57     static struct epoll_event ev, events[EPOLL_SIZE];
 58    //设置为可读et模式 events告诉内核要监听的事件    
 59     ev.events = EPOLLIN | EPOLLET;
 60 
 61     char message[BUF_SIZE];
 62     int epfd;
 63     int client, epoll_events_count;
 64 
 65     listener = socket(AF_INET, SOCK_STREAM, 0);
 66     if(listener < 0)
 67     {
 68         perror("create socket failed\n");
 69         return 1;
 70     }
 71     setnonblocking(listener);
 72     
 73     ret = bind(listener, (struct sockaddr*)&addr, sizeof(addr));
 74     if(ret < 0)
 75     {
 76         close(listener);
 77         return 1;
 78     }
 79 
 80     ret = listen(listener,1);
 81     if(ret < 0)
 82     {
 83         close(listener);
 84         return 1;
 85     }
 86   //创建一个epoll句柄
 87     epfd = epoll_create(EPOLL_SIZE);
 88     if(epfd < 0)
 89     {
 90         return 1;
 91     }
 92 
 93     ev.data.fd = listener;
 94   //epoll的三个动作 EPOLL_CTL_ADD  EPOLL_CTL_MOD  EPOLL_CTL_DEL
 95     ret = epoll_ctl(epfd, EPOLL_CTL_ADD, listener, &ev);
 96     
 97     while(1)
 98     {  //等待事件的产生
 99         epoll_events_count = epoll_wait(epfd, events, EPOLL_SIZE, -1);
100         int i;
101         for(i = 0; i < epoll_events_count; ++i)
102         {
103             if(events[i].data.fd == listener)
104             {
105                 client = accept(listener, (struct sockaddr*)&their_addr, &socklen);
106                 if(client < 0)
107                 {
108                     
109                 }
110                 setnonblocking(client);
111                 ev.data.fd = client;
112                 
113                 ret = epoll_ctl(epfd, EPOLL_CTL_ADD, client, &ev);
114 
115                 if(ret < 0)
116                 {
117 
118                 }
119             }
120             else
121             {
122                 handle_message(events[i].data.fd);
123             }
124         }    
125         
126     }
127 
128     close(listener);
129     close(epfd);
130     return 0;
131 }

 

游戏服务器学习进度之epoll

标签:style   blog   color   io   os   ar   for   sp   文件   

原文地址:http://www.cnblogs.com/wangkk/p/4034899.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!