我对线程做了个简单的封装,一个类从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;
}