epoll_ctl

一个简单的epoll使用例子

对着背影说爱祢 提交于 2019-11-28 13:47:46
核心代码,所有代码在这里 下载 #include "unixnet.h" #include "chat.h" #include "sys/epoll.h" /** * 改进说明:使用epoll进行事件回调,多用户可以处于输入命令状态(不再阻塞在登陆处) */ int main (int argc, char *argv[]) { int listen_fd; socklen_t cli_len; struct sockaddr_in cli_addr,serv_addr; int ret,flags; int re_use_addr=1; char recv_buf[MAXLINE]; int i; //epoll 描述符 int efd; struct epoll_event event; struct epoll_event events[MAXUSERS]; //初始化槽位 for(i=0; i<MAXUSERS; i++) { chater[i].slot_status =SLOT_FREED ; chater[i].sock_fd =-1; chater[i].cmd .cmd_type =-1; } /*AF_INET指定ipv4,SOCK_STREAM制定流模式,0为tcp*/ listen_fd = socket(AF_INET,SOCK_STREAM,0); if

epoll使用总结

非 Y 不嫁゛ 提交于 2019-11-28 09:02:22
epoll的使用总结 使用epoll来实现一个tcp server,中间碰到了不少使用细节上的问题,总结一下。 man epoll里推荐的使用方法 epoll使用代码 #define MAX_EVENTS 10 struct epoll_event ev, events[MAX_EVENTS]; int listen_sock, conn_sock, nfds, epollfd; /* Set up listening socket, 'listen_sock' (socket(), bind(), listen()) */ epollfd = epoll_create(10); if (epollfd == -1) { perror("epoll_create"); exit(EXIT_FAILURE); } ev.events = EPOLLIN; // 不要写成ev.events = EPOLLIN | EPOLLET; ev.data.fd = listen_sock; if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) { perror("epoll_ctl: listen_sock"); exit(EXIT_FAILURE); } for (;;) { nfds = epoll_wait

epoll 使用详解

妖精的绣舞 提交于 2019-11-28 09:01:41
epoll简介 epoll 是Linux内核中的一种可扩展IO事件处理机制,最早在 Linux 2.5.44内核中引入,可被用于代替POSIX select 和 poll 系统调用,并且在具有大量应用程序请求时能够获得较好的性能( 此时被监视的文件描述符数目非常大,与旧的 select 和 poll 系统调用完成操作所需 O(n) 不同, epoll能在O(1)时间内完成操作,所以性能相当高),epoll 与 FreeBSD的kqueue类似,都向用户空间提供了自己的文件描述符来进行操作。 int epoll_create(int size); 创建一个epoll的句柄,size用来告诉内核需要监听的数目一共有多大。当创建好epoll句柄后,它就是会占用一个fd值,在linux下如果查看/proc/进程id/fd/,是能够看到这个fd的,所以在使用完epoll后,必须调用close() 关闭,否则可能导致fd被耗尽。 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); epoll的事件注册函数,第一个参数是 epoll_create() 的返回值,第二个参数表示动作,使用如下三个宏来表示: EPOLL_CTL_ADD //注册新的fd到epfd中;EPOLL_CTL_MOD /

一个超级简单的服务器框架

你离开我真会死。 提交于 2019-11-27 23:24:57
1. 本服务器端框架采用epoll+线程池+任务队列 2. Epoll和sernasock是我封装的,ThreadPool用的是 http://blog.csdn.net/shreck66/article/details/50412986 Epoll.h /** * by:gzh * 2017.12.12 * 可以改进的地方:EPOLLIN 接收数据read()处可以优化, * 现在每次可以接收1kb的数据 */ #ifndef _GZH_EPOLL_H_ #define _GZH_EPOLL_H_ #include <vector> #include <functional> #include <condition_variable> #include <list> #include "net.h" namespace gzhlib { class GzhEpoll { public: typedef int Socket; typedef struct epoll_event EpollEvent; typedef struct sockaddr_in SocketAddr; typedef socklen_t SockLen; typedef std::tuple<Socket, const char*> ClientMessageTuple; typedef std:

Python探路-Nginx

假装没事ソ 提交于 2019-11-27 03:37:28
一直向写关于nginx的博客但是一直没有能够将nginx的内容形成自己的知识体系,所有没有勇气写下去。今天鼓起勇气写下这篇博客,也希望借此形成对nginx的整体认识。 首先看下nginx的进程模型: nginx一般是通过一个master进程+多个worker进程(和cpu核数一样多)的模式工作的。worker是master进程通过fork出来的,master用来监听连接,然后把连接交给worker进行处理和交互,除此之外,master还会监控worker进程的运行状态,如果有worker异常退出时,master还会重新启动新的worker。 那nginx是采用哪种方式工作的呢?答案是: 异步非阻塞 ,nginx一般启动多进程的方式,进程数和核数一致,而不会使用多线程,这是由于线程之间的切换会消耗cpu和内存,这也是nginx为什么能够使用异步非阻塞的原因,针对一个进程,它的任务就是不断的处理epoll里面的任务,当有任务被唤醒时就会被放到epoll中等待处理,如果epoll为空才会进入阻塞状态。 结合一个tcp连接的生命周期,我们看看nginx是如何处理一个连接的。首先,nginx在启动时,会解析配置文件,得到需要监听的端口与ip地址,然后在nginx的master进程里面,先初始化好这个监控的socket(创建socket,设置addrreuse等选项,绑定到指定的ip地址端口

select 和 epoll的区别

▼魔方 西西 提交于 2019-11-26 12:12:57
转载: https://blog.csdn.net/gymaisyl/article/details/83962671 select的缺点: 支持的fd数量有限: 单个进程能够监视的文件描述符的数量存在最大限制,通常是1024,当然可以更改数量,但由于select采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差;(在linux内核头文件中,有这样的定义:#define单个进程能够监视的文件描述符的数量存在最大限制,通常是1024,当然可以更改数量,但由于select采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差;(在linux内核头文件中,有这样的定义:#define __FD_SETSIZE 1024) 每次调用select, 都会把fd从用户态拷贝到内存态 ; 内核 / 用户空间内存拷贝问题,内核 / 用户空间内存拷贝问题,select需要复制大量的句柄数据结构,产生巨大的开销; 使用的是轮询的方式,需要内核遍历传进来的所有fd; select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件;select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件; select只提供了一个函数——select函数。而epoll提供了三个函数,epoll_create, epoll_ctl 和 epoll