linux epoll 单线程,epoll高并发多路复用,基于epoll的高性能服务器

并发测试工具ab使用

linux命令安装这个工具:apt-get install apache2

windows中装好apache之后就会再带一个工具

8a8eda213d5d9b8bd9e855eaecdd1e54.png

9e4b43121355d02c6cb9a9d6825541e7.png

windows命令使用方法

ab -n 200 -c 5 http://www.baidu.com/

1000就是测试的数量

-c 10 就是开启的线程数

测试的地址

5b8c89a80bec0d95e89a9a89eb17a8ec.png

反回了一些测试信息,如 使用时间,每次要多久等信息。

linux也是一样用的。

epoll多路复用IO 高并发

epoll多路复用是专门用来处理高并发的,在linux多路复用中有多种,

有epoll,select,其中select是在linux和windows中通用的,其中select用来做过超时处理,本身多路复用,为了高并发,目前只推荐

使用epoll在linux中,因为其他方案没有他的效率高,而且代码复杂度

不比他简单,epoll主要解决的问题是:

处理大量并发连接中,只有少量活跃的,(就是很多人连接过来,但是他们都没有断开)只有少数是活跃的, 如果都活跃那epoll也没提高效率.

web服务器处理的并发数量是有限的。

epoll连接有两种方式:一种是水平触发,LT(level triggered)他其实和select一样,有一个区别是select他是要遍历所有的路判断值,然后会导开销很大, 他的效率好select差不多.

还有一种是边缘触发,(edge-triggered)数据发生变化,有一个数据进来,它就会触发。

代码演示.

在acceppt这里每次都开一个线程,现在先不开线程了,先在一个线程中把所有的处理掉,通过多路复用实现这个功能.

多路复用头文件:(只能在linux使用)#include

基于epoll的高性能服务器。开发和高并发测试

里面都有注释:1 创建一个epoll 里面最多放256个套接字,然后注册事件(一个结构体)2确定把哪个socket注册到事件当中,这个是创建的socket用来做服务端的socket。3指定类型 EPOLLIN是数据进来的时候  EPOLLET 边缘触发模式 4把socket注册到epoll里面  EPOLL_CTL_ADD新增 一个socket到epoll当中 5//最多等待20个事件epoll_event event[20];

//发送发一个数据给客户端 意思大盖就是发送一个X给连接客户端

后面将HTTP协议,const char *msga = "HTTP/1.1 200 OK\r\nContent-Length: 1\r\n\r\nX";

等待 判断他是否有数据  20是最多等待20个事件.最后是超时时间 500毫秒int count = epoll_wait(epfd,event, 20, 500);

如果当前等待成功就会遍历当前的socket,

然后判断是哪种socket类型,如果是和客户进行连接的那就接收用户的

数据,并存储用户收发数据的socket,然后注册到epoll当中.

(短连接技术)

如果是与客户收发数据的socket那就调用发送接收接口,并且从client

中删掉这个socket, 因为以及用不到他了,等待下次连接上来的时候

就还需要accpet 进行边缘触发,就是这个原理>

如果发送两次.同时连接呢,ET边缘检查他只会产生一次,

这样会造成Accept被丢掉了,没处理到,所以和客户端bind的socket要设置成非阻塞的.

int main(int argc, char *argv[])

{

printf("RUN");

unsigned short port = 15987;

XTCP server;

printf("Bind");

if (!server.Bind(port))

{

printf("Bind error:%d", port);

return -1;

}

printf("Bind ok %d",port);

//单线程测试

//1 创建一个epoll 里面最多放256个套接字

int epfd = epoll_create(256);

//注册事件 一个结构体

epoll_event ev;

//确定把哪个socket注册到事件当中,

//这个是创建的socket用来做服务端的socket

ev.data.fd = server.m_sock;

//指定类型 EPOLLIN是数据进来的时候  EPOLLET 边缘触发模式

ev.events = EPOLLIN | EPOLLET;

//2  把socket注册到epoll里面  EPOLL_CTL_ADD新增 一个socket到epoll当中

epoll_ctl(epfd, EPOLL_CTL_ADD, server.m_sock, &ev);

//最多等待20个事件

epoll_event event[20];

char buf[1024] = { 0 };

//发送发一个数据给客户端

const char *msga = "HTTP/1.1 200 OK\r\nContent-Length: 1\r\n\r\nX";

int sizeaa = strlen(msga);

//如果发送两次 同时连接呢 ET边缘检查他只会产生一次

//这样会造成Accept被丢掉了,没处理到  所以和客户端bind的socket要设置称非阻塞的

server.SetBlock(false);

for (;;)

{

//3 等待 判断他是否有数据  最后是超时时间

int count = epoll_wait(epfd,event, 20, 500);

if (count <= 0)

continue;  //超时直接进入下一次

//变量所有事件 可能有建立连接  或 产生数据  怎么区分呢

for (int i = 0; i

{

memset(buf, 0, sizeof(buf));

//用来建立连接的socket

if (event[i].data.fd == server.m_sock)

{

///如果发送两次 同时连接呢 ET边缘检查他只会产生一次

//这样会造成Accept被丢掉了,没处理到  所以和客户端bind的socket要设置称非阻塞的

//死循环 读到返回空为止

for(;;)

{

XTCP client = server.Accept();

if(client.m_sock <= 0)break;  //处理了所有accept

//产生一个新的socket注册到epoll当中

ev.data.fd = client.m_sock;

ev.events = EPOLLIN | EPOLLET;

epoll_ctl(epfd, EPOLL_CTL_ADD, client.m_sock, &ev);

}

}

else

{

//对应的就是客户端的连接

XTCP client;

//取出socket值

client.m_sock = event[i].data.fd;

//接受 信息

client.Recv(buf, 1024);  // http只会发一次, 所以他不会多次数据没处理

//发送 信息  EPOLL_CTL_DEL删掉就行了

client.Send(msga, sizeaa);

epoll_ctl(epfd, EPOLL_CTL_DEL, client.m_sock, &ev);

client.Close();

}

}

//创建线程

// TcpThread *th = new TcpThread();

// th->client = client;

// std::thread sthr(&TcpThread::Main, th);

// // 释放主线程占用的资源

// sthr.detach();

}

server.Close();

printf("getchar()");

getchar();

return 0;

}

注意左边的知识代码 因为Epoll只能在; linux上使用

aa1917c41ccca9266f1f4a7ad0f5287f.png

当我们发现他发送的X,表示整个的多路复用的程序就运行起来了,

在用一个工具来测试一下,

ab -n 1000 -c 10 192.168.1.125:15988/

76dda901bb4f10e2d5e6c6062b0790b9.png

apache测试出的吞吐率为Requests per second:10102.54[#/sec](mean)

每秒请求达到上万

814ef9ba5eb15d0f486be300c3ce3813.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值