首页 > 代码库 > 游戏服务器学习进度之epoll
游戏服务器学习进度之epoll
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 else121 {122 handle_message(events[i].data.fd);123 }124 } 125 126 }127 128 close(listener);129 close(epfd);130 return 0;131 }
游戏服务器学习进度之epoll
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。