当前位置: 首页 > news >正文

统计局网站集约化建设方案网站数据库有哪些

统计局网站集约化建设方案,网站数据库有哪些,做网站用哪个电脑,seo搜索引擎优化公司优化poll进行拷贝的开销poll开销过大将整个 pollfd 数组拷贝到内核态,以便内核检查 fd 是否就绪(从用户态 → 内核态)。内核检查 fd 状态,并填充 revents。将 pollfd 数组从内核态拷贝回用户态,让应用程序可以读取 rev…

优化poll进行拷贝的开销

poll开销过大

  • 将整个 pollfd 数组拷贝到内核态,以便内核检查 fd 是否就绪(从用户态 → 内核态)。
  • 内核检查 fd 状态,并填充 revents。
  • 将 pollfd 数组从内核态拷贝回用户态,让应用程序可以读取 revents 里的就绪状态(从内核态 → 用户态)。

这个拷贝过程涉及 所有 pollfd 结构体,而 pollfd 结构体的大小通常是 8~16字节(取决于架构),如果监听 fd 数量很大(例如 上千个),拷贝数据量会很大,导致 系统调用的开销上升。

优化遍历开销

  • 优化 poll 遍历查询空位置的问题:poll 需要遍历整个 pollfd 数组来找到空闲位置,以便管理 fd,当 fd 数量庞大时,维护成本很高。
  • 优化遍历查询就绪 fd 的问题:poll 在返回时,仍然需要遍历整个 pollfd 数组来寻找就绪的 fd,时间复杂度为 O(n)。

epoll 的优化点(epoll_ctl + epoll_wait 分离)

操作说明
epoll_ctl只在你要添加/修改/删除监听 fd 时才调用一次,相当于“注册监听列表”
epoll_wait每次只等待事件,不关心你监听了哪些 fd,内核直接返回“就绪事件”

认识epoll的接口

poll 和select 都通过一个接口完成“注册 + 等待”,每次调用都要传递和检查全部 fd,效率低;
而epoll 将监听与等待分离,通过epoll_ctl 注册事件,通过epoll_wait 等待事件,减少了不必要的遍历和数据拷贝

epoll_create()

作用

创建一个 epoll 实例,并返回一个 epoll 文件描述符(epfd),该 epfd 用于后续的 epoll_ctl() 和 epoll_wait() 操作。

函数原型

int epoll_create(int size);这个参数已经进行废弃了,但是为了进行向前兼容没有将该参数进行删除。

返回值

  • 成功:返回 epfd(epoll 实例的文件描述符)。
  • 失败:返回 -1,errno 指示错误类型。

epoll_ctl()

作用

管理 epoll 监控的文件描述符,对epoll模型进行操作,包括添加、修改、删除操作。

函数原型

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

参数

  • epfd:由 epoll_create() 生成的 epoll 句柄。
  • op:操作类型,支持以下三种:

        EPOLL_CTL_ADD:添加一个新的 FD 到 epoll 实例。

        EPOLL_CTL_MOD:修改已有的 FD 监听的事件。

        EPOLL_CTL_DEL:从 epoll 实例中删除 FD。

  • fd:需要监听的文件描述符。
  • event:指向 struct epoll_event 结构体的指针,设置监听的事件类型。

返回值

  • 成功:返回 0。
  • 失败:返回 -1,errno 指示错误类型。

epoll_wait()

作用

等待被监听的文件描述符发生事件,并返回就绪的文件描述符。

函数原型

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

参数

  • epfd:epoll_create() 生成的 epoll 句柄。
  • events:用于存储发生事件的文件描述符,用户需提供足够的空间。
  • maxevents:events 数组的大小,建议大于 0。
  • timeout:超时时间(毫秒):

        0:立即返回(非阻塞)。

        -1:永远阻塞,直到有事件发生。        

        >0:等待指定时间。

返回值

  • 成功:返回就绪的文件描述符数量(nfds)。
  • 失败:返回 -1,errno 指示错误类型。

epoll的原理 

epoll服务器实现的框架

socket套接编程的封装

#pragma once#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "log.hpp"
#include "err.hpp"class Sock
{const static int backlog = 32;public:static int Socket(){// 1. 创建socket文件套接字对象int sock = socket(AF_INET, SOCK_STREAM, 0);if (sock < 0){logMessage(FATAL, "create socket error");exit(SOCKET_ERR);}logMessage(NORMAL, "create socket success: %d", sock);int opt = 1;setsockopt(sock, SOL_SOCKET, SO_REUSEADDR|SO_REUSEPORT, &opt, sizeof(opt));return sock;}static void Bind(int sock, int port){// 2. bind绑定自己的网络信息struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(port);local.sin_addr.s_addr = INADDR_ANY;if (bind(sock, (struct sockaddr *)&local, sizeof(local)) < 0){logMessage(FATAL, "bind socket error");exit(BIND_ERR);}logMessage(NORMAL, "bind socket success");}static void Listen(int sock){// 3. 设置socket 为监听状态if (listen(sock, backlog) < 0) // 第二个参数backlog后面在填这个坑{logMessage(FATAL, "listen socket error");exit(LISTEN_ERR);}logMessage(NORMAL, "listen socket success");}static int Accept(int listensock, std::string *clientip, uint16_t *clientport){struct sockaddr_in peer;socklen_t len = sizeof(peer);int sock = accept(listensock, (struct sockaddr *)&peer, &len);if (sock < 0)logMessage(ERROR, "accept error, next");else{logMessage(NORMAL, "accept a new link success, get new sock: %d", sock); // ?*clientip = inet_ntoa(peer.sin_addr);*clientport = ntohs(peer.sin_port);}return sock;}
};

epoll模型的封装

epollServer.hpp

#include <iostream>
#include<unistd.h>
#include<sys/epoll.h>
#include<functional>
#include<string>
#include"sock.hpp"
#include"log.hpp"
using namespace std;using func_t = function<string(const string&)>;
#define SIZE 1024const static int defultvalue=-1;
const static int defultnum=64;
class EpollServer
{
public:EpollServer(int port,func_t func,int num=defultnum):_listen_sockfd(defultvalue),_port(port),_num(num),_revs(nullptr),_func(func){}void serverInit(){//1、创建套接字_listen_sockfd=Sock::Socket();//2、进行bind绑定Sock::Bind(_listen_sockfd,_port);//3、设置监听状态Sock::Listen(_listen_sockfd);//4、创建epoll模型//4、1 创建epoll模型实例_epfd=epoll_create(1);if(_epfd<0){logMessage(FATAL,"创建epoll实例失败 :%s",strerror(errno));exit(EPOLL_CREATE_ERROR);}//4、2 管理epoll进行监控的文件描述符struct epoll_event events;events.events=EPOLLIN;events.data.fd=_listen_sockfd;epoll_ctl(_epfd,EPOLL_CTL_ADD,_listen_sockfd,&events);//5、进行开辟就是事件的空间_revs=new struct epoll_event[_num];logMessage(NORMAL,"进行epoll服务器初始化成功");}void serverStart(){int timeout=-1;for(;;){// 进行等待管理的文件描述符发生事件int n = epoll_wait(_epfd,_revs,_num,timeout);switch (n){case -1:logMessage(ERROR,"epoll_wait等待文件描述符发生事件失败");break;case 0:logMessage(NORMAL,"outtime....");break;default://一定有事件进行就绪HandlerEven(n); //将有多少个就绪的事件进行传入break;}}}void HandlerEven(int readyNum){for(int i=0;i<readyNum;i++){int sockfd=_revs[i].data.fd;uint32_t events=_revs[i].events;//处理监听套接字---listen套接字就绪if(sockfd==_listen_sockfd && events&EPOLLIN){string clienip;uint16_t port;int fd=Sock::Accept(sockfd,&clienip,&port);if(fd<0){logMessage(FATAL,"accept 获取链接失败");continue;;}//建立连接成功,我们可以直接进行读取吗???????  不可以!!!!//交给epollstruct epoll_event ev;ev.events=EPOLLIN;ev.data.fd=fd;epoll_ctl(_epfd,EPOLL_CTL_ADD,fd,&ev);}//处理普通套接字---普通套接字就绪else if(events&EPOLLIN){//进行读取客户端的消息char buffer[SIZE];ssize_t n=recv(sockfd,buffer,sizeof(buffer)-1,0);if(n>0){buffer[n]=0;logMessage(NORMAL,"client#  %s",buffer);//通过回调方法进行处理客户端的消息string resp=_func(buffer);//将处理过后的消息进行返回send(sockfd,resp.c_str(),resp.size(),0);}else if(n==0){epoll_ctl(_epfd,EPOLL_CTL_DEL,sockfd,nullptr);close(sockfd);logMessage(NORMAL,"客户端退出");}else{//细节:epoll_ctl(_epfd,EPOLL_CTL_DEL,sockfd,nullptr);close(sockfd);logMessage(ERROR,"进行读取客户端消息失败");}}else{}}}~EpollServer(){if(_listen_sockfd!=defultvalue){close(_listen_sockfd);}if(_epfd!=defultvalue){close(_epfd);}if(_revs){delete[] _revs;}}
private:int _listen_sockfd;int _port;int _epfd;struct epoll_event* _revs;int _num;func_t _func;
};

http://www.dtcms.com/a/565267.html

相关文章:

  • 自己动手写深度学习框架(快速学习python和关联库)
  • 从“算法思维”到“算子思维”:我在昇腾AI开发中的认知跃迁
  • 全球优秀企业网站工程公司资质等级
  • Hello epoll!
  • 泰安哪里做网站wordpress 男扮女
  • Linux】 性能调优实战:内核参数优化技巧
  • 网站建设厘金手指排名二一伊春网站制作
  • 做公众号关注网站网页安全防护怎么关闭
  • 【运维✨】云服务器公网 IP 迷雾:为什么本机看不到那个地址?
  • Swift 6.2 列传(第一篇):主线 Actor 的 “独尊令”
  • 基于AI大模型智能硬件--小智 AI 聊天机器人项目介绍
  • mybatis-plus SQL 注入漏洞导致版本升级引发的问题
  • 低空经济爆发期 遥感影像识别如何破解数据安全与效率困局
  • 哈尔滨做平台网站平台公司哪家好南通启益建设集团有限公司网站
  • 可以做婚礼视频的网站有哪些免费域名注册可解析
  • 网络抓包教学
  • Input getevent记录和InputReader,InputDispatcher启动
  • ESP01s通过blinker云端进行远程控制开关灯
  • 前端面试高频题解析
  • 模板网站修改教程南宁cms建站系统
  • 中天建设集团网站WordPress好像微博一样插件
  • 果蔬检测数据集VOC+YOLO格式16099张72类别
  • 电子沙盘数字沙盘智能吸附工具栏:高效作战新利器7
  • 关于asp sql网站开发的书籍微梦网站建设
  • 突破局域网限制!EMQX 结合 cpolar 实现 MQTT 远程通信全攻略
  • 【经典书籍】《人月神话》第八章“胸有成竹”精华讲解
  • 升级mybatis-plus导致项目启动报错: net.sf.jsqlparser.statement.select.SelectBody
  • 线性代数 - 线性方程组的原始解法(高斯消元法)
  • 深入 Lua 环境机制:全局变量的 “容器” 与 “隔离术”
  • 利用Github与Hexo搭建属于自己的在线个人博客