C++socket编程(六):6.4 epoll多路复用IO高并发
现在开始讲讲linux中epoll多路复用高并发
多路复用常用的有epoll,select等,前面已经讲过select处理延时阻塞的问题。而且时在windows上和linux上通用的。
重点:目前在linux中,只推荐用epoll处理多路复用的问题。其他方案,效率没他高而且,代码也不简单。
epoll处理那些问题:
·大量并发连接中只有少量活跃。
·LT(水平触发)(level triggered)
解释:与select一样,与select性能区别,要遍历所有的值,与会导致效率较低。
·ET(边缘触发)(edge-triggered)
解释:只是当数据发生了变化,才会触发一次。每一次触发之后需要将所有数据收完之后在做下一次处理。
如下代码:
整个流程分为三步:
一:创建epoll
二:注册事件
三:边缘检测(我们以ET为例)
//一:创建epoll,epoll_create()int epfd = epoll_create(256); //意思是创建一个epoll里面最多放256个套接字//二:注册事件:epoll_event ev;ev.data.fd = server.sock; //确定把哪一个socket注册到事件中去,就是刚刚创建的socket,做服务端的socketev.events = EPOLLIN | EPOLLET;epoll_ctl(epfd, EPOLL_CTL_ADD,server.sock,&ev); // 这样就把监听端口的socket注册到了epoll中epoll_event event[20]; //这次最多等待20个事件,就会返回,满了需要下次调用char buffer[1024] = { 0 };const char* message = "HTTP/1.1 200 OK\r\nContent-Length:8\r\n\r\nILOVEYOU";int size = strlen(message);for (;;){//三:边缘检测int count = epoll_wait(epfd,event, 20, 500);if (count <= 0)continue;for (int i = 0; i < count; i++){//每次长生的事件可能不只一个,产生的事件,产生的事件无法两种,建立连接,数据传输// 所以我们应该遍历处理,而且接下来的内容,//后面的章节将会用到http进行处理,if (event[i].data.fd == server.sock) //表示接收连接事件{XTcp client = server.Accept(); //接收到一个连接进来,产生一个新的socket,// 我们仍然需要将他注册到epoll中ev.data.fd = client.sock;ev.events = EPOLLIN | EPOLLET;epoll_ctl(epfd, EPOLL_CTL_ADD, client.sock, &ev); //第二个参数对应的accept时与客户端建立连接后创建的新的socket//如果这么一直注册下去能容纳的256个事件一定会满,所以要清理}else{XTcp client;client.sock = event[i].data.fd;//做模拟http协议的操作client.Recv(buffer, 1024);client.Send(message, size);epoll_ctl(epfd, EPOLL_CTL_DEL,client.sock, &ev);client.Close();}}
我们用ab工具测试下连接
ab -n 1000 -c 10 http://192.168.16.223:8888为例
发现测试卡死。分析原因
XTcp client = server.Accept(); 因为我们时ET模式,但是完全有可能时来了两个socket,两个事件同时来了,但是触发了一次边缘检测。
改后代码:
//一:创建epoll,epoll_create()int epfd = epoll_create(256); //意思是创建一个epoll里面最多放256个套接字//二:注册事件:epoll_event ev;ev.data.fd = server.sock; //确定把哪一个socket注册到事件中去,就是刚刚创建的socket,做服务端的socketev.events = EPOLLIN | EPOLLET;epoll_ctl(epfd, EPOLL_CTL_ADD,server.sock,&ev); // 这样就把监听端口的socket注册到了epoll中epoll_event event[20]; //这次最多等待20个事件,就会返回,满了需要下次调用char buffer[1024] = { 0 };const char* message = "HTTP/1.1 200 OK\r\nContent-Length:8\r\n\r\nILOVEYOU";int size = strlen(message);server.SetBlock(false);for (;;){//三:边缘检测int count = epoll_wait(epfd,event, 20, 500);if (count <= 0)continue;for (int i = 0; i < count; i++){//每次长生的事件可能不只一个,产生的事件,产生的事件无法两种,建立连接,数据传输// 所以我们应该遍历处理,而且接下来的内容,//后面的章节将会用到http进行处理,if (event[i].data.fd == server.sock) //表示接收连接事件{for (;;) //无限循环,读到返回为空为止{XTcp client = server.Accept(); //接收到一个连接进来,产生一个新的socket,// 我们仍然需要将他注册到epoll中if (client.sock <= 0)break;ev.data.fd = client.sock;ev.events = EPOLLIN | EPOLLET;epoll_ctl(epfd, EPOLL_CTL_ADD, client.sock, &ev); //第二个参数对应的accept时与客户端建立连接后创建的新的socket//如果这么一直注册下去能容纳的256个事件一定会满,所以要清理}}else{XTcp client;client.sock = event[i].data.fd;//做模拟http协议的操作client.Recv(buffer, 1024);client.Send(message, size);epoll_ctl(epfd, EPOLL_CTL_DEL,client.sock, &ev);client.Close();}}}
ab工具测试结果
C++socket编程(六):6.4 epoll多路复用IO高并发相关推荐
- nginx 多进程 + io多路复用 实现高并发
一.nginx 高并发原理 简单介绍:nginx 采用的是多进程(单线程) + io多路复用(epoll)模型 实现高并发 二.nginx 多进程 启动nginx 解析初始化配置文件后会 创建(for ...
- socket编程 及select poll epoll示例
[cpp] view plain copy 1.关于字节排序 网际协议采用大端字节序,来传输多字节整数. 系统提供了转换的宏定义,如果主机与网际协议相同,则宏定义为空. 2.客户端 ...
- Python基础----Socket编程规范及底层原理(三)---socketserver实现并发及底层原理
Socket网络编程: 前面实现的TCP服务端只能接受一个用户接入,这里使用了并发来实现多用户接入,不废话直接上代码!原理后面慢慢给大家讲! import socketserverclass MySe ...
- linux网络编程之socket编程(六)
经过一个国庆长假,又有一段时间没有写博文了,今天继续对linux网络编程进行学习,如今的北京又全面进入雾霾天气了,让我突然想到了一句名句:"真爱生活,珍惜生命",好了,言归正传. ...
- Socket编程实践(9) --套接字IO超时设置方法
引:超时设置3种方案 1. alarm超时设置方法 //代码实现: 这种方式较少用 void sigHandlerForSigAlrm(int signo) {return ; }signal(SIG ...
- GitHub:基于epoll机制的高并发聊天室,c语言实现
https://github.com/jwzh222/epoll 后期填坑.
- asyncio 文件io高并发_python教程:使用 async 和 await 协程进行并发编程
python 一直在进行并发编程的优化, 比较熟知的是使用 thread 模块多线程和 multiprocessing 多进程,后来慢慢引入基于 yield 关键字的协程. 而近几个版本,python ...
- 高并发网络编程之epoll详解
在linux 没有实现epoll事件驱动机制之前,我们一般选择用select或者poll等IO多路复用的方法来实现并发服务程序.在大数据.高并发.集群等一些名词唱得火热之年代,select和poll的 ...
- 高并发网络编程之epoll(个人遇到最好理解的一篇文章、易懂)
LT 和 ET本质的区别是: LT模式状态时,主线程正在epoll_wait等待事件时,请求到了,epoll_wait返回后没有去处理请求(recv),那么下次epoll_wait时此请求还是会返回( ...
最新文章
- Gartner2014年魔力象限(商业智能和分析平台)
- 在哥大计算机视觉读博的五年总结
- sysctl -p 重新加载文件/etc/sysctl.conf -a 所有参数 -w 临时指定
- Jenkins之gitlab配置
- windows应用程序框架及实例
- 【机器学习基础】关于异常检测的分享!
- SSIM(structural similarity index),结构相似性
- 开发composer包
- python写tcp服务器_用Python实现一个简单的多线程TCP服务器的教程
- 骚年,还在为歌荒发愁吗?python教你爬取网易云热门歌单
- 【TWVRP】基于matlab遗传算法求解多车场带时间窗的车辆路径规划问题【含Matlab源码 1035期】
- 单片机用C语言锯齿波,试用c语言编写一个能输出锯齿波信号的单片机c51程序
- unity3d面试题
- python excel 颜色填充 excel样式
- 苹果手机页面不兼容问题——mui
- OpenCV:详解阈值分割的处理
- STM32cubemx——超声波测距
- 千万别轻易裸辞,今年工作太难找了!
- 【centos】安装nvida CUDA平台附带安装cudnn库及TensorRT8
- 解读:电子合同存证五问五答
热门文章
- 哈密顿图 哈密顿回路 哈密顿通路(Hamilton)
- 观视屏《残疾人郑心意》所想
- 在.NET环境中实现每日构建(Daily Build)--ccnet,MSBuild篇
- 易语言客户端请求http_HTTP的重点问题
- 初学者python笔记(文件的操作)
- linux编译l和l区别,linux 下 g++编译程序时-I(大写i) 与-L(大写l)-l(小写l) 的作用详解...
- myisam读取速度为什么比innodb快_为什么MySQL用B+树做索引
- 2021年12月Python小屋编程比赛获奖名单
- Python可以这样学(第十季:网络爬虫实战)-董付国-专题视频课程
- Python编写编程作业批量自动打分程序的思路与实现