HTML5技术

记录一次线上组件崩溃的解决过程 - HarlanC(2)

字号+ 作者:H5之家 来源:H5之家 2017-06-22 10:01 我要评论( )

上面代码的背景是一个controller thread(简称CT)管理着多个Generator Thread(GT),CT会监控每个GT的状态,如果有的状态不是Active,那么就delete掉它的资源,调用这个析构函数的时候会释放掉GT所拥有的线程句柄(th

上面代码的背景是一个controller thread(简称CT)管理着多个Generator Thread(GT),CT会监控每个GT的状态,如果有的状态不是Active,那么就delete掉它的资源,调用这个析构函数的时候会释放掉GT所拥有的线程句柄(thread_)和线程使用的相关资源(generator_)(socket和应用层协议的相关资源),delete thread_之前需要先给这个thread发送一个stop()信号:

void GeneratorThread::stop() { (void) stopRequest_.set(); }

然后调用thread_->wait(5000)确保线程收到这个stop信号之后,采取delete thead_,为的是防止打断thread有可能正在进行的其他工作。通过抓到的dump文件,发现在这里跳出了exception。我们怀疑5秒的等待时间是不是太短了,于是改成了下面的代码:

GeneratorThread::~GeneratorThread() { if (thread_) { stop(); thread_->wait(INFINITE);//wait forever delete thread_; } delete generator_; }

问题依然得不到解决,继续研究,发现thread_包含的线程的真正句柄(thread_对象所属类的成员变量,windows线程函数_beginthreadex的返回值),此时已经变成了无效句柄。问题有眉目了,竟然没有注意到野指针问题,我们在删除一个指针之后,编译器只会释放该指针所指向的内存空间,而不会删除这个指针本身,因此,如果delete两次GeneratorThread,析构函数会进入两次,第二次执行下面这个句子的时候,虽然thread_已经被delete过了,但仍然能够进入

if(thread_)

这时候一个无效句柄调用wait函数,跳出了exception。如何修改就很简单了。

GeneratorThread::~GeneratorThread() { if (thread_) { stop(); thread_->wait(5000); delete thread_; thread_=nullptr; } delete generator_; generator_=nullptr; }

因此,看似复杂的问题往往是由一些低级错误造成的。反过来,如果写代码的时候如果不小心,一些小错误往往也会酿成大祸。

好了,最后是出补丁,release...

这篇博文结束了。

后续如果时间充足,会有工作中的其他总结,包括但不限于:

博客园是个藏龙卧虎的地方,最后插个广告,楼主目前就职公司要回流本土了,由于种种原因需要留在北京,所以又要换工作了。楼主工作快7年了,目标职位C++后台开发。对两个方向比较感兴趣:广告后台和人工智能。希望各路大神们收留或者推荐,感激不尽。

posted @

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 【线上问题】由防火墙导致的数据库空闲连接断开问题 - Trust_FreeDom

    【线上问题】由防火墙导致的数据库空闲连接断开问题 - Trust_FreeDom

    2017-06-15 16:00

  • localstorage和sessionstorage上手使用记录 - 蓓蕾心晴

    localstorage和sessionstorage上手使用记录 - 蓓蕾心晴

    2017-05-24 09:00

  • 学习HTML的第一次课 - 此人有病

    学习HTML的第一次课 - 此人有病

    2017-05-06 16:00

  • 如何快速处理线上故障 - 倒骑的驴

    如何快速处理线上故障 - 倒骑的驴

    2017-05-02 12:01

网友点评
t