查看单个帖子
  #1 (permalink)  
旧 2008-02-10
sjinny 的头像
sjinny sjinny 当前离线
普通会员
 
注册日期: 2008-02-01
帖子: 66
sjinny 正向着好的方向发展
默认 请教一下关于析构的问题……

我对线程做了个简单的封装,一个类从Active派生之后,调用它的activate函数就会激活一个线程来执行其中的activity函数。这是一个在Active里声明的纯虚函数:
private:
virtual void activity(void) =0;

但是现在遇到一个问题:如果我在桟上建立一个Active的派生类的实例,并且activate它,当桟把这个实例弹出时,会调用Active的析构函数,在这个析构函数里会调用join来等待线程结束。可是有时线程会开始的比较晚,一直到桟弹出时才开始执行,而这时这个实例已经在join等待状态了,于是在线程调用Active::activity()这个纯虚函数时,Active的派生类的那部分已经被析构了,activity的实现没了,这时线程就调用了那个纯虚函数,然后会输出:
pure virtual method called

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

虽然在桟弹出之前显示调用join能够解决这个问题,但是这依赖于使用者的记性,所以不是很好……
该怎么解决呢?

代码:
#include <boost/thread/thread.hpp> #include <boost/thread/recursive_mutex.hpp> using namespace boost; template< typename Message > class Active { public: Active() : _functor( *this ), _thread( NULL ) { } virtual ~Active() { join(); } public: void activate(void) { recursive_mutex::scoped_lock lock( _mutex ); if( !_thread ){ _thread= new thread( _functor ); } } void join(void) { recursive_mutex::scoped_lock lock( _mutex ); if( _thread ){ _thread->join(); delete _thread; _thread= NULL; } } void send( const Message& __msg ) { recursive_mutex::scoped_lock lock( _mutex ); } Message recv(void) { recursive_mutex::scoped_lock lock( _mutex ); } private: virtual void activity(void) =0; private: class Functor { public: Functor( Active& __active ) : _active( __active ) {} ~Functor() {} public: void operator () (void) { _active.activity(); } protected: Active& _active; }; private: Functor _functor; recursive_mutex _mutex; thread* _thread; };
代码:
#include "Active.h" class Loudspeaker : public Active< string > { public: void text( const string& __text ) { _text= __text; } private: virtual void activity(void) { for( int i= 0; i<5; ++i ){ printf( "%s", _text.c_str() ); //_sleep( 100 ); } } protected: string _text; }; int main( int argc, char* argv[] ) { Loudspeaker speaker[3]; speaker[0].text( "Test_0_!!\n" ); speaker[1].text( "Test_1_!!\n" ); speaker[2].text( "Test_2_!!\n" ); speaker[0].activate(); //_sleep( 100 ); //speaker[1].activate(); //_sleep( 100 ); //speaker[2].activate(); // speaker[0].join(); return 0; }
回复时引用此帖