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

icp网站备案管理系统佛山小网站建设

icp网站备案管理系统,佛山小网站建设,黄页广告公司,安卓app软件制作工具epoll是Linux提供一种多路复用的技术#xff0c;类似各个平台都支持的select#xff0c;只是epoll在内核的实现做了更多地优化#xff0c;可以支持比select更多的文件描述符#xff0c;当然也支持 socket这种网络的文件描述符。Linux上的大并发的接入服务器#xff0c;目前…epoll是Linux提供一种多路复用的技术类似各个平台都支持的select只是epoll在内核的实现做了更多地优化可以支持比select更多的文件描述符当然也支持 socket这种网络的文件描述符。Linux上的大并发的接入服务器目前的实现方式肯定都通过epoll实现。 epoll和线程 有很多开发人员用epoll的时候会开多个线程来进行数据通信比如一个线程专门accept(我个人早些年在FreeBSD用kqueue的时候由于对内部机制没有基本了解也这样搞)一个线程收发或者接收和发送都用各自独立的线程。 通常情况下accept独立线程是没必要的accept对于内核而言就应用程序从内核的未完成的SYN队列读取一点数据而已。具体参见 accept部分: TCP三次握手过程与对应的Berkeley Socket APIs的介绍 收发独立成两个线程也没有必要因为大部分的应用服务器通常情况下启动一个线程收发数据最大数据的收发量瓶颈在于网卡而不是CPU像网游接入服务器配置一个KM的网卡很少有游戏会申请1G的带宽那一台机器得有多少数据输入和输出。所以我们通信线程为epoll服务器就够了。 epoll的基本原理 为了让某些朋友能读得更连惯我还是说一下epoll基本原理。 epoll外部表现和select是一样的。他提供READ, WRITE和ERROR等事件。 大致流程像下面这样: 1. 应用注册感兴趣的事件到内核 2. 内核在某种条件下将事件通知应用程序 3. 应用程序收到事件后根据事件类型做对应的逻辑处理。 原理部分我再说一下不容易理解的地方包括水平触发和边缘触发WRITE事件的事件利用(这个可以结合参考文献1的kqueue的WRITE事件原理一致的)和修改事件的细节。 水平触发 READ事件socket recv buff有数据将一直向应用程序通知直到buff为空。 WRITE事件socket send buff从满的状态到可发送数据将一直通知应用程序直到buff满。 边缘触发 READ事件socket recv buff有数据了只通知应用一次不管应用程序有没有调用read api接下来都不通知了。 WRITE事件socket send buff从满的状态到可以发送数据只通知一次。 上面这个解释不知道大家能否理解也只能这样说了。有疑问的做一下试验。另外这些细节的东西前几年固定下来后这几年做的项目是直接用的也就很少在涉及细节是凭理解和记忆写下的文字万一有错请指正^-^。 WRITE事件的利用 这个还一下不好描述。大概描述一下详细看参考文献1。大致这样: 1. 逻辑层写数据到应用层的发送buff向epoll注册一下WRITE事件 2. 这时epoll会通知应用程序一个WRITE事件 3. 在WRITE事件响应函数里从应用层的发送buff读数据然后用socket send api发送。 因为我在很多实际项目中看到大家没有利用epoll的WRITE的事件来发数据特意地说一下。大部分的项目是直接轮询应用程序的发送队列我早期项目也是这么干的。 epoll的修改事件 对于这个我的映像比较深刻。epoll的修改事件比较坑爹不能单独修改某个事件怎么说呢比如epoll里已经注册了READWRITE事件你如果想单单重注册一下WRITE事件而且READ事件不变epoll的epoll_ctl API是做不到的你必须同时注册READWRITE这个在下面的代码中可以看到。FreeBSD的kqueue在这一点完全满足我们程序员的要求。 抽象epoll API 我把herm socket epoll封装部分贴出来让朋友们参考一下epoll的用法。大部分错误抛异常代码被我去掉了。 class Multiplexor { public:  Multiplexor(int size, int timeout -1, bool lt true);  ~Multiplexor(); void Run();  void Register(ISockHandler* eh, MultiplexorMask mask);  void Remove(ISockHandler* eh);  void EnableMask(ISockHandler* eh, MultiplexorMask mask);  void DisableMask(ISockHandler* eh, MultiplexorMask mask); private:  inline bool OperateHandler(int op, ISockHandler* eh, MultiplexorMask mask)  {   struct epoll_event evt;   evt.data.ptr eh;   evt.events mask;   return epoll_ctl(m_epfd, op, eh-GetHandle(), evt) ! -1;  } private:  int m_epfd;  struct epoll_event* m_evts;  int m_size;  int m_timeout;  __uint32_t m_otherMasks; }; Multiplexor::Multiplexor(int size, int timeout, bool lt)  {  m_epfd epoll_create(size);  if (m_epfd -1)   throw HERM_SOCKET_EXCEPTION(ST_OTHER);    m_size size;  m_evts new struct epoll_event[size]; m_timeout timeout; // sys/epoll.h is no EPOLLRDHUP(0X2000), dont add EPOLLRDHUP  m_otherMasks EPOLLERR | EPOLLHUP;  if (!lt)   m_otherMasks | EPOLLET; } Multiplexor::~Multiplexor() {  close(m_epfd);  delete[] m_evts; } void Multiplexor::Run() {  int fds epoll_wait(m_epfd, m_evts, m_size, m_timeout);   if (fds -1)  {   if (errno EINTR)    return;  }    for (int i 0; i fds; i)  {   __uint32_t evts m_evts[i].events;   ISockHandler* eh reinterpret_castISockHandler*(m_evts[i].data.ptr);   int stateType ST_SUCCESS;   if (evts EPOLLIN)    stateType eh-OnReceive(); if (evts EPOLLOUT)    stateType eh-OnSend(); if (evts EPOLLERR || evts EPOLLHUP)    stateType ST_EXCEPT_FAILED; if (stateType ! ST_SUCCESS)    eh-OnError(stateType, errno);  } } void Multiplexor::Register(ISockHandler* eh, MultiplexorMask mask) {  MultiplexorMask masks mask | m_otherMasks;  OperateHandler(EPOLL_CTL_ADD, eh, masks); } void Multiplexor::Remove(ISockHandler* eh) {  // Delete fd from epoll, dont need masks  OperateHandler(EPOLL_CTL_DEL, eh, ALL_EVENTS_MASK); } void Multiplexor::EnableMask(ISockHandler* eh, MultiplexorMask mask) {  MultiplexorMask masks mask | Herm::READ_MASK | Herm::WRITE_MASK;  OperateHandler(EPOLL_CTL_MOD, eh, masks | m_otherMasks); } void Multiplexor::DisableMask(ISockHandler* eh, MultiplexorMask mask) {  MultiplexorMask masks (Herm::READ_MASK | Herm::WRITE_MASK) (~mask);  if (!OperateHandler(EPOLL_CTL_MOD, eh, masks | m_otherMasks))   throw HERM_SOCKET_EXCEPTION(ST_OTHER); } 上面类就用到epoll_create(), epoll_ctl()和epoll_wait()以及几种事件。epoll用起来比select清爽一些。 大致用法类似下面这样 先定义一个Handler class StreamHandler : public Herm::ISockHandler {   public:   virtual Herm::Handle GetHandle() const;     virtual int OnReceive(int);   virtual int OnSend(int); }; 在OnReceive()处理收到数据的动作在OnSend()。。。。 在通信线程中大概类似这样的代码实际看情况。 Multiplexor multiplexor; StreamHandler sh; multiplexor.Register(sh, READ_EVT); multiplexor.Run(...);
http://www.yutouwan.com/news/28475/

相关文章:

  • 东营网站建设推广外接硬盘做创建立网站
  • 我想在阿里巴巴网站开店 怎么做旅游网络营销如何做
  • 网站建设与维护怎么学网站建设的风险预测
  • 金融网站策划方案烟台html5网站建设
  • 自己的网站怎么做进销存dw网站建设框架大小设定
  • 网站如何做伪静态发稿什么意思
  • 有哪些tp5做的网站用老域名做新网站
  • 山西省住房和城乡建设厅官方网站请多记几个本站域名防止失联
  • 免费的黄冈网站有哪些平台?济南建设局官网
  • 花都建设网站网络营销工具中最基本最重要的是
  • dede个人网站h5网站开发培训机构
  • 阿里云服务器安装网站深圳推广公司哪家好
  • 怎么选择徐州网站开发杭州网站设计步骤
  • 网站建设网站徒手整形培训网站的总体方案与功能设计
  • 网站建设实施方式桐城网站开发
  • php做的网站处理速度怎么样网站建设设置分享功能
  • 网站建设-纵横网络免费推广网站工具
  • 上海网站怎么备案表办公室设计方案
  • 王建设个人网站网络营销的目的和意义
  • 做高仿鞋子在什么网站卖好前十强排名家装公司
  • 站长工具如何使用wordpress 站内搜索代码
  • 东北建站网络服务中心
  • 拓者室内设计网站服务器可以吧网站做跳转吗
  • 广州黄埔建网站网页版梦幻西游是网易的吗
  • 网站开发ssh西安软件外包公司排名
  • 网站可以做多少个关键词服务网站 建设原则
  • 湖南服装网站建设头像制作免费软件
  • 都有哪些电商平台汕头seo计费管理
  • 网站开发者的设计构想网页制作有什么软件
  • 网站栏目划分怎么做建设邮费自己的网站_要不要购买服务器的