首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

OpenRTMFP/Cumulus Primer(22)线程逻辑分析之一:RTMFPServer线程的起步和等待

2012-09-11 
OpenRTMFP/Cumulus Primer(22)线程逻辑分析之一:RTMFPServer线程的启动和等待OpenRTMFP/Cumulus Primer(22

OpenRTMFP/Cumulus Primer(22)线程逻辑分析之一:RTMFPServer线程的启动和等待

OpenRTMFP/Cumulus Primer(22)RTMFPServer线程的启动和等待
  • 作者:柳大·Poechant(钟超 Michael)
  • 博客:Blog.csdn.net/poechant
  • 邮箱:zhongchao.ustc@gmail.com
  • 日期:August 5th, 2012

    1 Poco::Thread

    Cumulus 大量使用了 Poco 的线程库。一个简单的 Poco 线程的使用实例如下:

    class PoechantRunnable: public Poco::Runnable {    virtual void run() {        // your codes    }};int main() {    PoechantRunnable runnable;  // Image that it's a gift    Poco::Thread thread;        // And… thread is just like your girl    thread.start(runnable);     // Okay, give your sweet babe the gift :)    thread.join();    return 0;}

    2 封装一个可运行线程的类

    Cumulus 中实现了一个 StartableProcess 类,该类继承了 Runnable,就是上面那个 gift 喽。

    class StartableProcess : public Poco::Runnable{public:    StartableProcess(Startable& startable);private:    void run();    Startable& _startable;};

    可以看到其中有Startable& _startable引用成员,它并没有继承 Runnable,而是封装了StartableProcessPoco::Thread

    Poco::Thread            _thread;StartableProcess        _process;

    这里Startable封装了一个StartableProcess成员,与StartableProcess是有所区别的。接下俩我们看他们是怎么用的。

    3 启动RTMFPServer线程

    我们可以看到在 Startable 类的构造函数中初始化了_process成员,初始化线程成员并传入线程名,设定标志域(Flag Field)_stoptrue,因为它还没有调用启动函数。

    Startable::Startable(const string& name)    : _name(name),      _thread(name),      _stop(true),      _haveToJoin(false),      _process(*this) {}

    初始化_process时,调用StartableProcess构造函数:

    StartableProcess::StartableProcess(Startable& startable)    : _startable(startable){}

    传入_startable的引用。在 Cumulus 中所有的线程的可运行类都是继承自 Startable 类的,然后通过调用 start() 来启动,启动后会响应到 run()。下面我们以 RTMFPServer 线程为例。

    RTMFPServer 类是继承自 Startable 类的:

    class RTMFPServer    : private Gateway,      protected Handler,      private Startable,      private SocketHandler

    RTMFPServer 的构造函数:

    RTMFPServer::RTMFPServer(UInt32 cores)    : Startable("RTMFPServer"),      _sendingEngine(cores),      _receivingEngine(cores),      _pCirrus(NULL),      _handshake(_receivingEngine,      _sendingEngine,      *this,      _edgesSocket,*this,*this),      _sessions(*this) {}

    其中在初始化时调用了其父类的构造函数。接下来就要启动RTMFPServer线程了。

    所在线程调用者函数主线程main(…) 主线程RTMFPServer对象RTMFPServer::start()主线程RTMFPServer对象Startable::start()主线程RTMFPServer从Startable继承来的Thread成员Thread::start(…)RTMFPServerRTMFPServer对象从Startable继承来的StartableProcess成员StartableProcess::run()RTMFPServerRTMFPServer对象RTMFPServer::prerun()RTMFPServerRTMFPServer对象Startable::prerun()RTMFPServerRTMFPServer对象RTMFPServer::run()

    4 RTMFPServer线程等待

    RTMFPServer::run()实现线程的持续运行,主要是依靠这两行代码:

    while (!terminate)    handle(terminate);

    handle(…)函数很简单,如下只进行了sleep(...)giveHandle()两个操作。

    void RTMFPServer::handle(bool& terminate){    if (sleep() != STOP) {        giveHandle();    } else        terminate = true;}

    sleep(…)是 RTMFPServer 是从 Startable 继承而来的,声明如下:

    WakeUpType sleep(Poco::UInt32 timeout=0);

    定义如下:

    Startable::WakeUpType Startable::sleep(UInt32 timeout) {    if (_stop)        return STOP;     WakeUpType result = WAKEUP;     if (timeout>0) {         if (!_wakeUpEvent.tryWait(timeout))             result = TIMEOUT;     } else {         _wakeUpEvent.wait();     }    if (_stop)        return STOP;    return result;}

    在运行状态下,_stopfalse,而默认参数timeout0,所以会调用:

    _wakeUpEvent.wait();

    这个_wakeUpEvent成员是一个Poco::Event对象,Poco::Event有一个使用方式就是在调用Poco::Event::wait()后,会一直等待Poco::Event::set()被调用后,才会跳出 wait 的状态。在 Cumulus 中 set 的动作是由:

    • RTMFPServer::requestHandle()
    • PoolThread::push(Poco::AutoPtr<RunnableType>& pRunnable)

      执行的。

      -

      转载请注明柳大·Poechant(钟超)的CSDN博客:Blog.CSDN.net/Poechant

      -

热点排行