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

刚做的网站怎么在百度搜到软件开发定制价格表

刚做的网站怎么在百度搜到,软件开发定制价格表,有趣的网站游戏,太原网站建设小程序上一篇:Linux–多路转接之select epoll epoll 是 Linux 下多路复用 I/O 接口 select/poll 的增强版本#xff0c;它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统 CPU 利用率。它是 Linux 下多路复用 API 的一个选择#xff0c;相比 select 和 poll#xff0c… 上一篇:Linux–多路转接之select epoll epoll 是 Linux 下多路复用 I/O 接口 select/poll 的增强版本它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统 CPU 利用率。它是 Linux 下多路复用 API 的一个选择相比 select 和 pollepoll 提供了更高的性能并且使用起来也更加方便。 epoll的工作原理 eventpoll框架的核心在于它能够高效地处理多个文件描述符上的事件避免了传统I/O多路复用机制如select和poll中的轮询开销。eventpoll通过以下方式实现 注册文件描述符当文件描述符被注册到eventpoll时会创建一个epitemeventpoll item结构体用于表示该文件描述符及其关心的事件类型。这个epitem会被插入到eventpoll的红黑树rbtree中以便快速查找和管理。等待事件发生通过调用epoll_wait()系统调用应用程序会在eventpoll的等待队列wq上等待。此时指定的回调函数是default_wake_function用于在事件发生时唤醒等待的线程。事件通知当被监测的文件描述符上有事件发生时会调用ep_poll_callback()回调函数将相应的epitem插入到eventpoll的就绪链表rdllist中。epoll_wait()会从这个链表中取出epitem并将对应的事件通知给应用程序。 注意以上操作均有系统自主完成 epoll 的相关系统调用 epoll_create() 创建一个 epoll 的句柄. #include sys/epoll.h int epoll_create(int size);size 参数用于告诉内核这个监听列表epoll 实例打算同时监视多少个文件描述符。 返回值 如果调用成功epoll_create 返回一个新的文件描述符该描述符用于后续的 epoll_ctl()和 epoll_wait()调用。 如果调用失败则返回 -1并设置 errno 以指示错误原因。 epoll_ctl() 允许程序在 epoll 实例中添加、修改或删除文件描述符file descriptors的监听事件. #include sys/epoll.h int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);参数说明 epfd由 epoll_create () 函数生成的 epoll 实例的文件描述符。op指定要执行的操作常用的值包括 EPOLL_CTL_ADD向 epoll 实例注册新的文件描述符和事件。 EPOLL_CTL_MOD修改已注册的文件描述符的事件。 EPOLL_CTL_DEL从 epoll 实例中删除一个文件描述符。fd要操作的目标文件描述符即要注册、修改或删除的文件描述符。event指向 struct epoll_event 结构体的指针该结构体包含了要注册或修改的事件信息。对于 EPOLL_CTL_DEL 操作该参数可以为 NULL。 typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t; struct epoll_event { uint32_t events; /* 事件类型 */ epoll_data_t data; /* 与事件相关的数据 */ }; events这是一个位掩码用于指示发生的事件类型。常见的事件类型包括 EPOLLIN表示对应的文件描述符可以进行读操作。 EPOLLOUT表示对应的文件描述符可以进行写操作。 EPOLLERR表示发生错误。 EPOLLHUP表示挂起hang up事件比如对端关闭了连接。 EPOLLET将事件设置为边缘触发Edge Triggered模式这是与水平触发Level Triggered模式相对的一种触发模式。 EPOLLONESHOT:用于确保事件被触发一次后除非再次使用 epoll_ctl 重新注册否则不再接收该事件。 data这是一个联合体可以存储与事件相关的数据。它提供了多种方式来关联事件和特定的数据或文件描述符 ptr可以指向任意类型的数据通常用于存储用户自定义的数据结构指针。 fd直接存储文件描述符的值当只需要管理文件描述符时这种方式更为直接(常用)。 u32 和 u64分别提供了32位和64位的无符号整数存储这些字段可以用来存储特定的值或标识符。 epoll_wait() 程序调用 epoll_wait 时它会阻塞当前线程直到注册在 epoll 实例上的文件描述符上有事件发生或者超时时间到达。 #include sys/epoll.h int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);参数说明 epfd由 epoll_create 函数生成的 epoll 实例的文件描述符。events指向 struct epoll_event 数组的指针用于存储发生的事件。当 epoll_wait 返回时该数组将被填充有发生事件的文件描述符和事件类型的信息。maxevents指定 events 数组的最大长度即 epoll_wait 一次可以处理的最大事件数。timeout指定等待 I/O 事件发生的超时时间毫秒。如果设置为 -1则 epoll_wait 将无限期地等待直到有事件发生。如果设置为 0则 epoll_wait 将立即返回无论是否有事件发生。如果设置为一个正整数则 epoll_wait 将等待指定的毫秒数如果在这段时间内有事件发生则返回否则返回 0表示超时。 返回值 成功时epoll_wait 返回发生事件的文件描述符数量。如果返回 0则表示在指定的超时时间内没有事件发生。如果发生错误epoll_wait 返回 -1并设置 errno 以指示错误原因。 epoll的工作方式 水平触发Level Triggered, LT 工作原理在水平触发模式下只要被监控的文件描述符上有可读写事件发生即数据到达但未被读取或可写空间可用但未被写入epoll_wait就会通知用户程序。 如果数据到达但是没有被读取或者可写空间可用但是没有被写入epoll_wait会再次通知用户程序直到相应的操作被执行。 特点 通知次数只要条件满足就会不断地通知。读写策略可以更灵活地处理读写不需要连续读取或写入直到遇到错误。效率由于频繁的通知可能会引起较多的上下文切换影响效率。编程复杂度相对容易理解和使用。 边缘触发Edge Triggered, ET 工作原理边缘触发模式是一种更高效的触发方式。在这种模式下epoll_wait仅在状态变化时通知用户程序一次比如从无数据到有数据或者从不可写变为可写。 当收到一个可读事件时需要一直读取数据直到返回EAGAIN错误表示没有更多数据可读。同样对于可写事件需要一直写入数据直到不能再写入为止。 知次数只在状态发生变化时通知一次。 读写策略读操作需要一直进行直到遇到EAGAIN错误写操作也是如此需要一直写直到无法继续写入。 效率减少了系统调用的次数提高了应用程序的效率。 编程复杂度要求程序必须更加小心地处理事件以避免错过任何事件这使得编程变得更加复杂。 主要区别 .水平触发LT边缘触发ET通知次数只要条件满足就会不断地通知只在状态发生变化时通知一次读写策略可以更灵活地处理读写读操作需要一直进行直到遇到EAGAIN错误写操作也是如此效率可能会引起较多的上下文切换影响效率减少了系统调用的次数提高了应用程序的效率编程复杂度相对容易理解和使用要求程序必须更加仔细地处理事件以避免错过任何事件编程复杂度高 epoll_server实例LT方式 我们将对上一篇的select_server进行一定的修改即可 epollServer.hpp #pragma once #include iostream #include string #include memory #include sys/epoll.h #include InetAddr.hpp #include Socket.hpp #include Log.hppusing namespace socket_ns;class EpollServer {const static int gnum 64; public:EpollServer(uint16_t port 8080): _port(port),_listensock(std::make_uniqueTcpSocket()),_epfd(-1){// 1. 创建listensockInetAddr addr(0, _port);//0表示任意ip_listensock-BuildListenSocket(addr);// 2. 创建epoll模型_epfd ::epoll_create(128);//返回值是epoll的fdif (_epfd 0){LOG(FATAL, epoll_create error\n);exit(5);}LOG(DEBUG, epoll_create success, epfd: %d\n, _epfd);// 3. 只有一个listensock, listen sock 关心的事件读事件struct epoll_event ev; //结构体包含事件的信息ev.events EPOLLIN;//事件可读ev.data.fd _listensock-SockFd(); //将listenfd放入到信息中epoll_ctl(_epfd, EPOLL_CTL_ADD, _listensock-SockFd(), ev);}//对事件的处理void handlerEvent(int num){for (int i 0; i num; i)//可处理多个事件{// 逐一将事件取出uint32_t revents _revs[i].events;int sockfd _revs[i].data.fd;// 读事件就绪if (revents EPOLLIN){if (sockfd _listensock-SockFd())//监听fd表示将创建连接fd{InetAddr clientaddr;int newfd _listensock-Accepter(clientaddr); // 不会被阻塞事件已知被响应if (newfd 0)continue;// 获取新链接成功struct epoll_event ev;ev.events EPOLLIN;ev.data.fd newfd;epoll_ctl(_epfd, EPOLL_CTL_ADD, newfd, ev);//将新事件添加到epoll中LOG(DEBUG, _listensock ready, accept done, epoll_ctl done, newfd is: %d\n, newfd);}else//表示连接的fd有事情发生{char buffer[1024];ssize_t n ::recv(sockfd, buffer, sizeof(buffer), 0); //接收客户端数据if (n 0){LOG(DEBUG, normal fd %d ready, recv begin...\n, sockfd);buffer[n] 0;std::cout client say# buffer std::endl;std::string echo_string server echo# ;echo_string buffer;::send(sockfd, echo_string.c_str(), echo_string.size(), 0);//将结果返回}else if (n 0)//表示连接已被断开没有断开无数据传输将阻塞于epoll{LOG(DEBUG, normal fd %d close, me too!\n, sockfd);// 对端连接关闭了::epoll_ctl(_epfd, EPOLL_CTL_DEL, sockfd, nullptr);::close(sockfd);}else{::epoll_ctl(_epfd, EPOLL_CTL_DEL, sockfd, nullptr); // 这里表示将epoll中的sockfd删除::close(sockfd);//而fd是拷贝进去的只是将拷贝在epoll中的fd擦除对应的fd事件还没有被关闭}}}}}//循环执行void Loop(){int timeout -1;//表示epoll阻塞等待直到有事件发生while (true){int n ::epoll_wait(_epfd, _revs, gnum, timeout);//用于等待事件的发生switch (n){case 0://规定时间内无事件发生LOG(DEBUG, epoll_wait timeout...\n);break;case -1://发生错误LOG(DEBUG, epoll_wait failed...\n);break;default://有事件发生LOG(DEBUG, epoll_wait haved event ready..., n : %d\n, n);handlerEvent(n);break;}}}~EpollServer(){_listensock-Close();//关闭listen_fdif (_epfd 0)//关闭epoll的fd::close(_epfd);} private:uint16_t _port; //端口号std::unique_ptrSocket _listensock; //监听sockint _epfd; //epoll的fdstruct epoll_event _revs[gnum];//事件数组存储对应事件 }; _epfd: epoll是Linux底层中一种高效的I/O多路复用机制所以也是属于一种事件需要在用户层创建对应的文件描述符用于表示对epoll的创建 _revs : 虽然在底层有红黑树来进行存储对应的事件但是在用户层是无法了解到底层的存储执行的因为epoll的底层全由系统来完成的用户无法操作所以还需要一个事件数组来存储对应的事件。 初始化 128是设置这次的最大事件管理数量相比于select来说他是无上限的比较灵活 对于事件的控制 将事件信息包含在ev结构体中即可 Loop: 这里我们将事件数组放入到函数中当 epoll_wait 返回时该数组将被填充有发生事件的文件描述符和事件类型的信息。这样就不用我们手动添加到事件数组中。 正是因为底层的红黑树会先存储着对应的事件信息当被监测的文件描述符上有事件发生时将相应的epitem插入到eventpoll的就绪链表rdllist中。epoll_wait()会从这个链表中取出epitem放到_revs中所以调用该函数会存到事件数组中。 handlerEvent: EPOLLIN是0x001, revents如果对应位上是可读的如0x003那么就能表示读事件就绪了 main.cc #include epollServer.hpp #include Log.hpp#include iostream #include memory// ./selectserver port int main(int argc, char *argv[]) {if (argc ! 2){std::cout Usage: argv[0] port std::endl;return 0;}uint16_t port std::stoi(argv[1]);EnableScreen();std::unique_ptrEpollServer svr std::make_uniqueEpollServer(port);svr-Loop();return 0; }注ET模式相对来说比较复杂需要涉及到非阻塞的程序等下一篇Reactor再详细展示。 epoll的优点 支持水平触发LT和边缘触发ET接口简单易用没有最大文件描述符数量的限制 select 和 poll 都有文件描述符数量的限制而 epoll 则没有。只管理“活跃”的连接epoll 会检查注册在其上的所有 socket只将那些真正活跃的 socket 返回给用户即减少了无效的等待时间。高效处理大量并发连接epoll能够高效地处理大量并发连接尤其适用于只有少量活跃连接的大量并发场景。它通过内核与用户空间共享一个事件表来跟踪所有需要监控的文件描述符当文件描述符的状态发生变化时内核会通知用户空间从而避免了传统方法中的线性扫描。提高CPU利用率epoll在等待事件就绪时如果就绪队列中没有事件会主动让出CPU从而提高了CPU的利用率。这使得epoll在处理大量并发连接时能够更加高效地利用系统资源。
http://www.dnsts.com.cn/news/71843.html

相关文章:

  • 网站后台费用白城网站建设哪家好
  • 邯郸邯山区网站建设邵阳汽车网站建设
  • 异构国际设计公司网站网站备案报道
  • 装饰网站建设套餐报价wordpress 网页慢
  • 网站服务器自己做温州vi设计公司
  • 二手网站专业做附近人的有吗门面设计效果图
  • iis7.5添加网站企业做网站需要提交的资料表格
  • 软件工程排名搜索引擎优化包括
  • 购物网站建设策划买域名送网站
  • 网站模板插件网站开发需要什么服务器
  • 做外单阿里的网站网站外链应该怎么做
  • 个人备案 网站名称 例子杭州建设网站免费
  • 门户网站建设经验青岛网上房地产官网查网签
  • 邢台网站建设联系电话哈尔滨大型网站开发
  • 上海网站快速排名制作人物的软件
  • 思政部网站建设总结北京seo网站设计
  • 网站建设微盘下载福州网站制作维护服务
  • 廊坊网站推广的公司猫咪多用户wordpress
  • 重庆市建设工程施工安全管理总站网站做seo需要些什么软件
  • 网加速器网络优化工程师是干嘛的
  • 无锡seo网站管理成都网站建设定
  • 跨境购物网站建设sae wordpress 更新
  • 做折扣的网站公司简介模板怎么做
  • 山西企业建站系统平台开源零代码平台
  • 沈阳网站建设思路深圳网页设计公司建设
  • 怎么制作网站的网页设计soho 网站建设
  • 乔智云智能建站江宁住房和城乡建设局网站
  • 广州化妆品网站制作如何引用404做网站
  • 淄博网站开发选网泰wordpress底部添加工信部链接
  • 长春火车站照片建设网站后需要什么知识