标准C++与线程 (一)

2014-11-24 12:55:07 · 作者: · 浏览: 5

标准C++和标准库中没有对线程的封装,程序员们不得不使用OS提供的API来处理线程,OS级别的API通常基于C,能用,但并不方便。最近看到论坛上有人问,顺便和同事讨论这个问题,如何使用标准C++封装线程的操作,目的就是simple and easy to use。想想自己似乎多年前(已经结蜘蛛网了)写过这方面的代码,找了找,还真找到了,是Windows平台的,整理一下,与大家分享。

// 抽象类,作为线程类的基类,定义了几个接口

// abstract class to provide interface.
//
class GeneralThread
{
public:
virtual ~GeneralThread() {}

public:
// create thread and run with specified priority
virtual void Run( long priority = THREAD_PRIORITY_BELOW_NORMAL ) = 0;
// wait thread running till timeout
virtual unsigned long Join( unsigned long ms = INFINITE ) = 0;

virtual unsigned long GetExitCode() const = 0;

// end thread ingore thread status.
virtual void End() {}
};

typedef GeneralThread GThread;
typedef GThread * CThreadPtr;

// 一个子类,实现了基类的接口,并且定义了一个新的接口来运行真正的线程函数

// 因此,可以从这个类继续派生新的子类,实现自定义的线程函数。

// a derived calss from GeneralThread
//
class SomeThread : public GeneralThread
{
public:
SomeThread() : m_hThread(0)
{
}

~SomeThread()
{
//Join( INFINITE );
if( m_hThread )
{
CloseHandle( m_hThread );
m_hThread = NULL;
}
}
public:
// new interface to implement thread actions
virtual unsigned long ThreadProc() = 0;

public:
virtual void Run( long priority )
{
m_hThread = CreateThread( NULL, 0, &SomeThread::ThreadProc, this, CREATE_SUSPENDED, NULL );

if( m_hThread )
{
SetThreadPriority( m_hThread, priority );
ResumeThread( m_hThread );
}
else
{
DWORD dw = GetLastError();
UNREFERENCED_PARAMETER( dw );
}
}

virtual unsigned long Join( unsigned long ms )
{
unsigned long ul = WAIT_OBJECT_0;

if( m_hThread )
{
ul = WaitForSingleObject( m_hThread, ms );

switch( ul )
{
case WAIT_OBJECT_0:
//GetExitCodeThread( m_hThread, &m_exitCode );
break;

case WAIT_TIMEOUT:
break;

case WAIT_FAILED:
ul = ul;
break;
}
}

return ul;
}

virtual unsigned long GetExitCode() const
{
DWORD exitCode = 0;
GetExitCodeThread( m_hThread, &exitCode );
return exitCode;
}

virtual void End()
{
TerminateThread( m_hThread, 0xabcd );
}

private:
static unsigned long WINAPI ThreadProc( LPVOID lpParameter )
{
SomeThread *p = static_cast< SomeThread * >( lpParameter );
return p->ThreadProc();
}

private:
HANDLE m_hThread;
};

// 虽然可以从SomeThread 派生子类,但是如果有多个线程,并且每个线程的线程函数不一样的话,

// 那么需要实现多个子类,并不是很方便。考虑到标准C++推荐使用模板和函数对象,因此派生了一个

// 子类,重新实现了父类中的虚函数,转发成对函数对象的访问。

//
// if you want to implement your thread, you have to derive a class from SomeThread and also implement your thread procedure.
// sometimes you will feel boring.
// so here we implement a template class to simplify usage.
// thus you don't need to code your derived class, instead just provide your function object.
//
template< typename F >
class ConcreteThread : public SomeThread
{
public:
ConcreteThread( const F &f ) : m_f(f)
{
}

private:
unsigned long ThreadProc()
{
return m_f();
}

private:
F m_f;
};

template< typename F >
CThreadPtr MakeThread( F &f )
{
return new ConcreteThread< F >( f );
}

// 这个类提供了另一种形式的封装。

// this class is just for simple usage in stack scope.
//
class Thread
{
public:
template< typename F >
Thread( F &f ) : m_pThread( MakeThread(f) )
{
m_pThread->Run();
}

~Thread()
{
delete m_pThread;
}

public:
unsigned long Join()
{
return m_pThread->Join();
}

unsigned long ExitCode()
{
return m_pThread->GetExitCode();
}

private:
CThreadPtr m_pThread;
};

代码不长,而且加了些注释,不难理解。下面是测试用的代码

int sum( int end )
{
int sum = 0;
for( int i = 0 ; i < end ; i++ )
{
sum += i;
}
return sum;
}

void TestThread()
{
// test Thread class
Thr