加入收藏 | 设为首页 | 会员中心 | 我要投稿 衡阳站长网 (https://www.0734zz.cn/)- 数据集成、设备管理、备份、数据加密、智能搜索!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

实例:一个服务器程序的架构介绍

发布时间:2019-01-29 18:45:33 所属栏目:外闻 来源:高性能服务器开发
导读:本文将介绍我曾经做过的一个项目的服务器架构和服务器编程的一些重要细节。 一、程序运行环境 操作系统:Centos 7.0 编译器:gcc/g++ 4.8.3、cmake 2.8.11 mysql数据库:5.5.47 项目代码管理工具:Visual Studio 2013 一、程序结构 该程序总共有 17 个线程

当任务产生时,只要我们将执行任务的函数 push_back 到 m_functors 这个 stl::vector 对象中即可。但是问题来了,如果是其他线程产生的任务,两个线程同时操作 m_functors,必然要加锁,这也会影响效率。muduo 是这样做的:

  1. void add_task(const Functor& cb)   
  2. {   
  3.     std::unique_lock<std::mutex> lock(mutex_);   
  4.     m_functors.push_back(cb);      
  5. }   
  6.  
  7. void do_task()   
  8. {   
  9.     std::vector<Functor> functors;   
  10.     {   
  11.         std::unique_lock<std::mutex> lock(mutex_);   
  12.         functors.swap(m_functors);   
  13.     }   
  14.  
  15.     for (size_t i = 0; i < functors.size(); ++i)   
  16.     {   
  17.         functors[i]();   
  18.     }   

看到没有,利用一个栈变量 functors 将 m_functors 中的任务函数指针倒换(swap)过来了,这样大大减小了对 m_functors 操作时的加锁粒度。前后变化:变化前,相当于原来 A 给 B 多少东西,B 消耗多少,A 给的时候,B 不能消耗;B 消耗的时候A不能给。现在变成A将东西放到篮子里面去,B 从篮子里面拿,B 如果拿去一部分后,只有消耗完了才会来拿,或者 A 通知 B 去篮子里面拿,而 B 忙碌时,A 是不会通知 B 来拿,这个时候 A 只管将东西放在篮子里面就可以了。

  1. bool bBusy = false;   
  2. void add_task(const Functor& cb)   
  3. {   
  4.     std::unique_lock<std::mutex> lock(mutex_);   
  5.     m_functors_.push_back(cb);   
  6.  
  7.     //B不忙碌时只管往篮子里面加,不要通知B   
  8.     if (!bBusy)   
  9.     {   
  10.         wakeup_to_do_task();   
  11.     }   
  12. }   
  13.  
  14. void do_task()   
  15. {   
  16.     bBusy = true;   
  17.     std::vector<Functor> functors;   
  18.     {   
  19.         std::unique_lock<std::mutex> lock(mutex_);   
  20.         functors.swap(pendingFunctors_);   
  21.     }   
  22.  
  23.     for (size_t i = 0; i < functors.size(); ++i)   
  24.     {   
  25.         functors[i]();   
  26.     }   
  27.  
  28.     bBusy = false;   

看,多巧妙的做法!

(编辑:衡阳站长网)

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

热点阅读