EPOLL
今天因为
epoll
的ET模式丢失了connect事件
,无脑调试了一天才发现错误在哪,特此记录一下。
只用epoll的ET模式时,多个cennect
可能只触发一个事件
,因此要循环accept
,直到返回-1
且error
被置为WAGAIN
或者WEOULDBLOCK
才退出循环。不然就会丢失connect事件
。
epoll的LT和ET的区别
LT:水平触发,效率会低于ET触发,尤其在大并发,大流量的情况下。但是LT对代码编写要求比较低,不容易出现问题。LT模式服务编写上的表现是:只要有数据没有被获取,内核就不断通知你,因此不用担心事件丢失的情况。
ET:边缘触发,效率非常高,在并发,大流量的情况下,会比LT少很多epoll的系统调用,因此效率高。但是对编程要求高,需要细致的处理每个请求,否则容易发生丢失事件的情况。
下面举一个列子来说明LT和ET的区别(都是非阻塞模式,阻塞就不说了,效率太低):
采用LT模式下, 如果accept调用有返回就可以马上建立当前这个连接了,再epoll_wait等待下次通知,和select一样。
但是对于ET而言,如果accpet调用有返回,除了建立当前这个连接外,不能马上就epoll_wait还需要继续循环accpet,直到返回-1,且errno==EAGAIN
- 参考:http://www.voidcn.com/article/p-qhcylfuz-bkv.html
man 7 epoll
while(1)
{
struct sockaddr_in client_address;
socklen_t len = sizeof client_address;
int connfd = accept(listenfd, (struct sockaddr*)&client_address, &len);
if(connfd == -1)
{
if(errno == EAGAIN || errno == EWOULDBLOCK)
{
break;
}
}
else
{
addfd(epollfd, connfd, true);
}
}
两个函数
sendfile();
copy_file_range();
以上两个函数输入必须是可以映射到内存的文件,输出sendfile()必须是套接字,copy_file_range()没有限制。
GDB
//TODO
调试多线程程序
http://logan.tw/posts/2015/11/01/debug-multithreaded-program-with-gdb/
其它
关于switch
的一个小问题,每个case
要用花括号,之前很少用没注意过这个问题,可以参考这里:https://stackoverflow.com/questions/5685471/error-jump-to-case-label