2012-11-10 43 views
3

我想写一个类,它将在其对象创建时运行一个线程,并在对象被删除后停止线程。删除boost ::线程后裔

class MyThread : public boost::thread { 

public: 

    MyThread() : bAlive(true) { 
     boost::thread(&MyThread::ThreadFunction,this); 
    } 

    ~MyThread() { 
     { 
      boost::unique_lock<boost::mutex> lock(Mutex); 
      bAlive=false; 
     } 
     ConditionVariable.notify_one(); 
     join(); 
    } 

private: 

    volatile bool bAlive; 
    boost::mutex Mutex; 
    boost::condition_variable ConditionVariable; 

    void ThreadFunction() { 
     boost::unique_lock<boost::mutex> lock(Mutex); 
     while(bAlive) { 
      ConditionVariable.timed_wait(lock,boost::get_system_time()+ boost::posix_time::milliseconds(MAX_IDLE)); 

      /******************************************* 
      * Here goes some code executed by a thread * 
      *******************************************/ 

     } 
    } 

}; 

从理论上讲,我想马上尽快唤醒线程了,因为它需要完成,所以我只好用TIMED_WAIT而不是睡眠。 这工作正常,直到我尝试删除此类的一个对象。在大多数情况下,它会正常删除,但偶尔它会在condition_variable.hpp,thread_primitives.hpp或crtexe.c中导致错误。有时我会收到通知:“释放后在3da804中修改了自由堆3da7a8”,有时候我没有。是的,我知道timed_wait的虚假唤醒,在这种情况下并不重要。 你能指点我的问题来源吗?我究竟做错了什么?

+0

不太清楚的问题是什么,有没有问号在这个问题 – jcw

回答

1

我看到你想要做什么,但是当你想到它不起作用:

MyThread foo; 

默认构造一个boost ::线程(因为MyThread的是自boost ::线程派生)。 默认构造函数创建一个引用Not-a-Thread的boost :: thread实例。

MyThread() { 
    boost::thread(&MyThread::ThreadFunction,this); 
} 

实际上是创建一个不同的线程,你忽略了返回的对象(有效的线程)。然后

~MyThread() { 
    // ... 
    join(); 
} 

试图加入到默认的构造线程(抛出一个异常析构函数内),你永远不会加入,实际上做的工作线程。


首先,不要从boost :: thread派生。创建一个成员变量来代替:

class MyThread { 
// ... 
private: 
    // ... 
    boost::thread _thread; 
}; 

在构造函数中,创建和线程分配给成员变量:

MyThread() { 
    _thread = boost::thread(&MyThread::ThreadFunction,this); 
} 

,并调用其join()方法在你的析构函数。

~MyThread() { 
    // ... 
    _thread.join(); 
} 

这应该可以解决您的问题。


但是,如果你只是想退出时,你的对象被销毁(并没有将其唤醒,而它的运行)的线程,你可以使用不同的方法。取消互斥和条件变量并改为使用中断。这将导致睡眠()抛出一个异常,所以你必须抓住它:

void ThreadFunction() { 
    try { 
     for(;;) { 
      boost::this_thread::sleep(boost::posix_time::milliseconds(MAX_IDLE)); 
      // Here goes some code executed by a thread 
     } 
    } catch(const boost::thread_interrupted& e) { 
     // ignore exception: thread interrupted, exit function 
    } 
} 

当线程被中断,这将立即退出ThreadFunction。如果您不需要线程在每个循环中休眠,则可以用boost::this_thread::interruption_point()替换它。如果线程中断,这只会引发异常。

现在,你可以简单地中断线程在析构函数:

MyThread::~MyThread() { 
    _thread.interrupt(); 
    _thread.join(); 
} 
+0

谢谢你很多!这已经帮助解决了我的问题。 – user1814683