OpenRTMFP/Cumulus Primer(20)Cumulus的一个线程启动 Bug

OpenRTMFP/Cumulus Primer(20)Cumulus的一个线程启动 Bug

  • 作者:柳大·Poechant(钟超)
  • 邮箱:zhongchao.ustc#gmail.com(# -> @)
  • 博客:Blog.CSDN.net/Poechant
  • 日期:June 25th, 2012

Cumulus 中的线程都是继承自 Startable,在其中封装 Poco::Thread 成员,使得一些有关线程的操作更方便。Startable 中的 start 函数如下:


void Startable::start() {
    if(!_stop) // if running
        return;
    ScopedLock
  
  
   
    lock(_mutex);
    
   
   if(_haveToJoin) {
        _thread.join();
        _haveToJoin=
   
   false;
    }
    
   
   try {
        DEBUG(
   
   "Try to start up a new thread inherited from Startable");
        _thread.start(_process);
        _haveToJoin = 
   
   true;
        ScopedLock
   
   
    
     lock(_mutexStop);
        _stop=
    
    false;
    } 
    
    catch (Poco::Exception& ex) {
        ERROR(
    
    "Impossible to start the thread : %s",ex.displayText().c_str());
    }
}

   
   
  
  

这样一个类继承 Startable 的话,并启动时传入自己,则会调用到 Startable::start(),然后调用到该类自己的 run() 函数。一般来说这个函数会一个循环,以 SocketManager 为例:


void SocketManager::run() {
    … 
    while(running()) {
    …
    }
}

我们要看看这个 running() 是怎么回事,如下:


inline bool Startable::running() const {
    return !_stop;
}

很简单,就是通过 Startable::_stop 成员来判断是否还需要继续循环下去。那么这个 _stop 是什么时候被设置为 false 的呢?就是上面的 start(),这里存在的一个问题就是先 start 线程,再设置 _stop 为 false。


_thread.start(_process);
_stop=false;

而 start() 之后 run() 的时候就开始通过 running() 来判断 _stop 值了。所以你会在使用 Cumulus 时,发现有时候启动起来的线程个数不对。正常情况下应该有四个线程:

icon Resize

它们是:

  • 主线程
  • RTMFPServer 线程
  • MainSockets 线程
  • RTMFPManager 线程

而异常情况可能是 MainSockets 没有启动,甚至 MainSockets 和 RTMFPManager 都没有启动。

MainSockets 没有启动的情况,这时客户端是无法接入成功的。

icon Resize

MainSockets 和 RTMFPManager 都没有启动的情况 T.T

icon Resize

具体是哪个线程没有启动成功可以通过 GDB 查看。

解决办法就是将 _stop 的设置操作,在启动线程之前。不过要注意锁要同时移动,并且在产生异常时设置 _stop 值为 true。


void Startable::start() {
    if(!_stop) // if running
        return;
    ScopedLock
  
  
   
    lock(_mutex);
    
   
   if(_haveToJoin) {
        _thread.join();
        _haveToJoin=
   
   false;
    }
    
   
   try {
        DEBUG(
   
   "Try to start up a new thread inherited from Startable");
        {
            ScopedLock
   
   
    
     lock(_mutexStop);
            _stop=
    
    false;
        }
        _thread.start(_process);
        _haveToJoin = 
    
    true;
    } 
    
    catch (Poco::Exception& ex) {
        {
            ScopedLock
    
    
     
      lock(_mutexStop);
            _stop = 
     
     true; 
     
     // June 25th, 2012, Michael@YY
        }
        ERROR(
     
     "Impossible to start the thread : %s",ex.displayText().c_str());
    }
}

    
    
   
   
  
  

-

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

-

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
流放之路最新汉化 【特别注意】 1.建议打汉化方式,先还原英文,再打汉化,免的受上一次汉化文件残留的影响。 2.本次汉化使用新的汉化方法汉化前务必看【图文使用教程.doc】 【更新说明】 1.根据 自己喜欢选择 相应版本 2.更新 ChY.zip:方正准圆字体,繁体整合版,确保系统已安装字体,字体设置文件失效勿用。修正巴哈小退之后登陆界面乱码(保留登陆界面英文) 3.更新 Cht2.zip:微軟正黑體 Bold字体,巴哈繁体 11.01 2版,保留原版字体 【字体说明】 Common.ui 为字体设置文件,所有汉化默认是微软雅黑,可自行更改为自己喜欢的字体 方正准圆:字体较大,适合满屏装备是迅速找到想要的装备,但是部分翻译由于过长,导致重叠 微软雅黑:标准配置,字体大小适中,看个人喜欢 【版本说明】按发布时间排列 ChY:繁体整合版 推荐!~ Cht2:巴哈论坛 发布的繁体版 11.01 2版 Cht:月下残雪v2 繁体版 10-24 0400 Chs:月下残雪v2 简体版 暂无 ChX:简体整合版 暂无 backup:为英文备份文件,覆盖还原用。暂无 【合理升级建议】 1.创建备份,比如Content.ggpk.eng 2.每次升级都是已覆盖旧文件形式,所以建议先把Content.ggpk(打过汉化补丁)升级,如果进 游戏汉化还在说明好用,如果汉化没了建议等新的汉化补丁。如果想尝试旧的汉化补丁是否能用 ,万一出错,这个时候备份的Content.ggpk.eng就起到恢复的作用。 【整合汉化的优点】 1.繁体、简体合体版,可供选择 2.天赋界面等字体不重叠 3.全文件汉化,部分英文是作者未完成 4.经过本人测试,避免不必要的失败 【打汉化补丁后不能进游戏修复方法】 方法1:备份Content - 副本.ggpk改名为Content.ggpk,重新打最新汉化补丁 方法2:可以运行游戏根目录下的PackCheck.exe,等待其自动修复为英文原版,直到出现提示“press any key to continue”就修复完成了。重新打最新汉化补丁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

钟超

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值