加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 业界 > 正文

实例:一个处事器措施的架构先容

发布时间:2019-01-20 23:21:59 所属栏目:业界 来源:高性能服务器开发
导读:本文将先容我曾经做过的一个项目标处事器架构和处事器编程的一些重要细节。 一、措施运行情形 操纵体系:Centos 7.0 编译器:gcc/g++ 4.8.3、cmake 2.8.11 mysql数据库:5.5.47 项目代码打点器材:Visual Studio 2013 一、措施布局 该措施总共有 17 个线程

事变线程的流程:

  1. while (!m_bQuit)   
  2. {   
  3.     epoll_or_select_func();   
  4.  
  5.     handle_io_events();   
  6.  
  7.     handle_other_things();   

个中 epoll_or_select_func() 等于上文所说的通过 select()/poll()/epoll() 等 IO multiplex 技能,确定好了哪些 TcpConnection 上稀有据到来。我的处事器代码中一样平常只会监测 socket 可读变乱,而不会监测 socket 可写变乱。至于怎样发数据,文章后头会先容。以是对付可读变乱,以 epoll 为例,这里必要配置的标识位是:

  • EPOLLIN 平凡可读变乱(当毗连正常时,发生这个变乱,recv()/read()函数返接纳到的字节数;当毗连封锁,这两个函数返回0,也就是说我们配置这个标识已经可以监测到新来数据和对端封锁变乱)
  • EPOLLRDHUP 对端封锁变乱(linux man 手册上嗣魅这个变乱可以监测对端封锁,但我现实调试时发送纵然对端封锁也没触发这个变乱,如故是EPOLLIN,只不外此时挪用recv()/read()函数,返回值会为0,以是现实项目中是否可以通过配置这个标识来监测对端封锁,如故待考据)
  • EPOLLPRI 带外数据

muduo 内里将 epoll_wait 的超事势件配置为 1 毫秒,我的另一个项目将 epoll_wait 超时时刻配置为 10 毫秒。这两个数值供各人参考。

这个项目中,事变线程和主线程都是上文代码中的逻辑,主线程监听侦听socket 上的可读变乱,也就是监测是否有新毗连来了。主线程和每个事变线程上都存在一个 epollfd。假如新毗连来了,则在主线程的 handle_io_events() 中接管新毗连。发生的新毗连的socket句柄挂接到哪个线程的 epollfd 上呢?这里采纳的做法是 round-robin 算法,即存在一个工具CWorkerThreadManager 记录了各个事变线程上事变状态。伪码大抵如下:

  1. void attach_new_fd(int newsocketfd)   
  2. {   
  3.     workerthread = get_next_worker_thread(next);   
  4.     workerthread.attach_to_epollfd(newsocketfd);   
  5.     ++next;   
  6.     if (next > max_worker_thread_num)   
  7.         next = 0;   
  8. }   

即先从第一个事变线程的 epollfd 开始挂接新来 socket,接着累加索引,这样下次就是第二个事变线程了。假如以是超出事变线程数量,则从第一个事变从头开始。这里办理了新毗连 socket “负载平衡”的题目。在现实代码中尚有个必要留意的细节就是:epoll_wait 的函数中的 struct epoll_event 数目开始到底要配置几多个才公道?存在的记挂是,多了挥霍,少了不足用,我在曾经一个项目中直接用的是 4096:

  1. const int EPOLL_MAX_EVENTS = 4096;   
  2. const int dwSelectTimeout = 10000;   
  3. struct epoll_event events[EPOLL_MAX_EVENTS];   
  4. int nfds = epoll_wait(m_fdEpoll, events, EPOLL_MAX_EVENTS, dwSelectTimeout / 1000); 

我在陈硕的 muduo 收集库中发明作者才用了一个较量好的思绪,即动态扩张数目:开始是 n个,当发明有变乱的 fd 数目已经达到 n 个后,将 struct epoll_event 数目调解成 2n 个,下次假如还不足,则酿成 4n 个,以此类推,作者奇妙地操作 stl::vector 在内存中的持续性来实现了这种思绪:

  1. //初始化代码   
  2. std::vector<struct epoll_event> events_(16);   
  3.  
  4. //线程轮回内里的代码   
  5. while (m_bExit)   
  6. {   
  7.     int numEvents = ::epoll_wait(epollfd_, &*events_.begin(), static_cast<int>(events_.size()), 1);   
  8.     if (numEvents > 0)   
  9.     {   
  10.         if (static_cast<size_t>(numEvents) == events_.size())   
  11.         {   
  12.             events_.resize(events_.size() * 2);   
  13.         }   
  14.     }   

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读