返回   cpper编程论坛 > Blog > polyrandom
注册账号 论坛帮助 会员列表 日历事件 搜索 今日新帖 标记版面已读

为这篇文章评分

初始化错误 - 线程和同步变量

发表于 2007-02-28 08:36 PM 作者: polyrandom
  • 初始化顺序仍然是C++里面最普遍的错误之一
  • 在多线程情况下,初始化顺序会变得更加难以寻找
  • 改变类的继承顺序或是成员变量位置可以简单地改正初始化顺序

在我负责的程序里面,我们有一个用fiber实现的后台处理过程。这部分程序由于使用fiber,所以其实一直占着主线程的时间,通常情况下会把fps降低一半左右。因此这次准备把这段程序放到D3D Present的间歇中去。因为Present不是异步的,我们必须把单线程程序改成多线程的。我的选择是,在另一个线程里面写Present。

这样一个小小的修改,包括设计、编码、测试和改错,花了近一天的时间,最后终于通过检查,commit上去了。下午在调试另一个程序的时候,进入调试模式n次中,突然有一次程序死锁在初始化过程中。于是反复重现,发现一个错误,大致代码如下:

代码:
class MyThread : Thread
{
    Semaphore lock_;
    uint threadFunc( void* )
    {
        for(;;)
        {
            lock_.get();
            doSth();
        }
    }
};
这样的代码看上去很简单,Thread类的构造函数会创建线程并且进入循环,然后每次得到信号就处理一下。但是实际上在进入threadFunc中lock_.get()语句的时候,lock_可能还没有被构造,因为C++里面,基类先构造,然后才是成员变量。

要修改这个问题很简单,把代码改成:

代码:
class MyThread : Semaphore,Thread
{
    uint threadFunc( void* )
    {
        for(;;)
        {
            get();
            doSth();
        }
    }
};
就行了,此时可以保证Semaphore先被创建。

看来,小处还是不能随便呀。
评论 0 Email文章
评论总数 0

评论

发表评论 发表评论
作者为 polyrandom 的最新文章

所有时间均为格林尼治时间 +9。现在的时间是 12:38 AM


Powered by vBulletin® 版本 3.7.0
版权所有 ©2000 - 2009,Jelsoft Enterprises Ltd.
(C) Copy Right All Right Reserved 2001 - 2007

Search Engine Friendly URLs by vBSEO 3.1.0