编程知识 购物 网址 新闻 笑话 | 软件 日历 阅读 图书馆 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
   -> C++ -> live555 epoll 实现 -> 正文阅读

[C++]live555 epoll 实现

  live555的任务调度是基于select的,其实select也不是很差,主要看使用场合,在并发量不是很大的时候效果还是很好的,而且很多平台都支持。当然,在Linux下有更好的选择,那就是epoll,将live555的任务调度改为epoll,能够进一步提高网络事件的处理能力,我在 BasicTaskScheduler 下添加了对epoll的支持,并没有删除select的实现,这样可以同时在windows和linux下编译使用。下面贴出主要部分,后面会给出代码的下载地址。
SingleStep 修改:

 1 void BasicTaskScheduler::SingleStep(unsigned maxDelayTime) 
 2 {
 3     // ....

4 unsigned timeout = tv_timeToDelay.tv_sec*1000+(tv_timeToDelay.tv_usec/1000); 5 struct epoll_event events[1] = {0}; 6 7 int numEvent = epoll_wait(_epollfd, events, 1, timeout); 8 if(numEvent < 0) 9 { 10 if (errno != EINTR) 11 internalError(); 12 } 13 else 14 { 15 HandlerDescriptor* handler = NULL; 16 int conditionSet = 0; 17 for(int i=0; i<numEvent; i++) 18 { 19 if(events[i].data.ptr == NULL) 20 continue; 21 handler = (HandlerDescriptor*)(events[i].data.ptr); 22 conditionSet = 0; 23 if(events[i].events & EPOLLIN) 24 conditionSet |= SOCKET_READABLE; 25 if(events[i].events & EPOLLOUT) 26 conditionSet |= SOCKET_WRITABLE; 27 if(events[i].events&EPOLLERR || events[i].events&EPOLLPRI) 28 conditionSet |= SOCKET_EXCEPTION; 29 30 if ((conditionSet&handler->conditionSet) != 0 31 && handler->handlerProc != NULL ) 32 { 33 fLastHandledSocketNum = handler->socketNum; 34 (*handler->handlerProc)(handler->clientData, conditionSet); 35 } 36 } 37 } 38 39 // .... 40 }

setBackgroundHandling 修改:

void BasicTaskScheduler
  ::setBackgroundHandling(int socketNum, int conditionSet, BackgroundHandlerProc* handlerProc, void* clientData) 
{
    // ...
        
    HandlerIterator iter(*fHandlers);   
        HandlerDescriptor* handler = NULL;
        while ((handler = iter.next()) != NULL) // lookupHandler
        {
          if (handler->socketNum == socketNum) 
            break;
        }
        struct epoll_event event = {0};
        event.data.ptr = handler;
        if (conditionSet&SOCKET_READABLE) 
            event.events |= EPOLLIN;
        if (conditionSet&SOCKET_WRITABLE) 
            event.events |= EPOLLOUT;
        if (conditionSet&SOCKET_EXCEPTION) 
            event.events |= (EPOLLPRI|EPOLLERR);
        if(epoll_ctl(_epollfd, EPOLL_CTL_ADD, socketNum, &event) < 0)
        {
            if(errno == EEXIST)
                epoll_ctl(_epollfd, EPOLL_CTL_MOD, socketNum, &event);
        }             
      
    // ...
}

moveSocketHandling 修改:

void BasicTaskScheduler::moveSocketHandling(int oldSocketNum, int newSocketNum)
{
    // ...
    
    HandlerIterator iter(*fHandlers);        
    HandlerDescriptor* handler = NULL;
    while ((handler = iter.next()) != NULL) // lookupHandler
    {
      if (handler->socketNum == oldSocketNum) 
        break;
    }

    if(!handler)
        return ;

    struct epoll_event event = {0};
    event.data.ptr = handler;    
    if(handler->conditionSet&SOCKET_READABLE)  
        event.events |= EPOLLIN;
    if(handler->conditionSet&SOCKET_WRITABLE)  
        event.events |= EPOLLOUT;
    if(handler->conditionSet&SOCKET_EXCEPTION) 
        event.events |= (EPOLLPRI|EPOLLERR);
    if(event.events != 0)
    {
        epoll_ctl(_epollfd, EPOLL_CTL_DEL, oldSocketNum, NULL);
        epoll_ctl(_epollfd, EPOLL_CTL_ADD, newSocketNum, &event);
    }

#if defined(__linux) || defined(__linux__) 
    struct epoll_event event = {0};
    event.data.ptr = handler;    
    if(handler->conditionSet&SOCKET_READABLE)  
        event.events |= EPOLLIN;
    if(handler->conditionSet&SOCKET_WRITABLE)  
        event.events |= EPOLLOUT;
    if(handler->conditionSet&SOCKET_EXCEPTION) 
        event.events |= (EPOLLPRI|EPOLLERR);
    if(event.events != 0)
    {
        epoll_ctl(_epollfd, EPOLL_CTL_DEL, oldSocketNum, NULL);
        epoll_ctl(_epollfd, EPOLL_CTL_ADD, newSocketNum, &event);
    }
#else
     // ...
#endif
    // ...
}

epoll的主要实现就是这些,我在windows和linux下编译通过,做了简单的测试,如果有什么疑问可以提出。后续我会给出live555多线程的实现。
我把代码放在了github,希望对你有帮助 ^_^
代码: https://github.com/PHZ76/live555_epoll
  C++ 最新文章
关于poin与references
019:别叫,这个大整数已经很简化了!
c++智能指针详解
BZOJ1269: [AHOI2006]文本编辑器editor
洛谷P3835 【模板】可持久化平衡树
洛谷P2925 [USACO08DEC]干草出售Hay For Sa
POJ 2987 Firing
树的重心
第一章 作业7.
【左神算法课】超经典:求两单向链表交点(
上一篇文章      下一篇文章      查看所有文章
加:2017-12-08 23:24:14  更:2017-12-08 23:24:17 
 
360图书馆 软件开发资料 购物精选 新闻资讯 Chinese Culture 三丰软件 开发 中国文化 阅读网 日历 万年历 2019年10日历
2019-10-19 21:24:27
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程知识