15,473
社区成员




// HEADER FILE : thread.h
// Thread.h: interface for the CThread class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_THREAD_H__07971CDB_D943_4826_903B_1BA1FF7634A6__INCLUDED_)
#define AFX_THREAD_H__07971CDB_D943_4826_903B_1BA1FF7634A6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <afxmt.h>
#include <windows.h>
typedef unsigned (WINAPI* THREAD_FUNC)(void *ThreadParam);
class CThread;
typedef struct tagThreadParam
{
CThread *pThread;
void *pParam;
} tThreadParam ;
class CThread
{
public:
CThread(THREAD_FUNC ThreadFunc, void *ThreadParam = NULL, bool bCreateSuspended = false, SECURITY_ATTRIBUTES* pSecurityAttributes = NULL, const char* ThreadName = NULL);
virtual ~CThread() { stop(100); }
int Start();
int Suspend();
int Resume();
void stop(unsigned long dwWait = INFINITE);
int Run();
HANDLE GetThreadHandle() const { return m_hThreadHandle; }
long GetThreadID() const { return m_nThreadID; }
operator HANDLE() const { return m_hThreadHandle; };
const char* GetThreadName() const { return (const char *)m_szThreadName; }
bool IsInvalid() const { return m_hThreadHandle <= 0 ? true : false; };
bool IsSuspended() const { return m_bSuspend; };
bool IsStopped() const { return m_bStopFlag; };
bool IsRunning();
private:
CThread(const CThread& ) {}
CThread& operator=( const CThread& ) {}
private:
bool m_bSuspend;
HANDLE m_hThreadHandle;
unsigned int m_nThreadID;
char m_szThreadName[512];
bool m_bStopFlag;
SECURITY_ATTRIBUTES*p_Attr;
THREAD_FUNC m_ThreadFunc;
void *m_pInputParam;
};
static unsigned WINAPI thread_function(void* pArg)
{
return ((CThread*)pArg)->Run();
}
#endif // !defined(AFX_THREAD_H__07971CDB_D943_4826_903B_1BA1FF7634A6__INCLUDED_)
// CPP FILE: thread.cpp
// Thread.cpp: implementation of the CThread class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "Thread.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#include "thread.h"
#include <process.h>
CThread::CThread(THREAD_FUNC ThreadFunc, void *ThreadParam, bool bCreateSuspended, SECURITY_ATTRIBUTES* pSecurityAttributes, const char* ThreadName):
p_Attr(pSecurityAttributes), m_hThreadHandle(0)
{
m_bStopFlag = false;
m_bSuspend = bCreateSuspended;
m_nThreadID = 0;
memset(m_szThreadName, 0, sizeof(m_szThreadName));
strncpy(m_szThreadName, ThreadName, min(strlen(ThreadName), sizeof(m_szThreadName) - 1));
m_ThreadFunc = ThreadFunc;
m_pInputParam = ThreadParam;
}
int CThread::Start()
{
tThreadParam param;
param.pParam = m_pInputParam;
param.pThread = this;
BOOL bRet = _beginthreadex(
p_Attr,
0,
m_ThreadFunc,//thread_function,
¶m,//this,
(m_bSuspend ? CREATE_SUSPENDED : 0 ),
&m_nThreadID);
m_hThreadHandle = (HANDLE)bRet;
m_ThreadFunc = thread_function;
return bRet;
}
// simulate to realize it
int CThread::Run()
{
while(!IsStopped())
{
int sum = 0;
for(int i = 0; i < 100; i ++)
{
sum += i;
}
printf("%d\n", sum);
Sleep(100);
}
_endthreadex(EXIT_SUCCESS);
return 0;
}
void CThread::stop(unsigned long dwWait)
{
if(IsInvalid())
return;
::WaitForSingleObject(m_hThreadHandle, dwWait);
m_bStopFlag = true;
}
int CThread::Suspend()
{
if(IsInvalid())
{
return -2;
}
if(::SuspendThread(m_hThreadHandle) == -1)
{
return -1;
}
m_bSuspend = true;
return 0;
}
int CThread::Resume()
{
if(IsInvalid())
{
return -2;
}
if(::ResumeThread(m_hThreadHandle) == -1)
{
return -1;
}
m_bSuspend = false;
return 0;
}
bool CThread::IsRunning()
{
if(IsInvalid())
return false;
if(m_bSuspend)
return false;
if(::WaitForSingleObject(m_hThreadHandle, 0) == WAIT_TIMEOUT)
return true;
else
return false;
}
DWORD IsThreadRunning(HANDLE hThread,BOOL &bRunning)
{
DWORD dwRet = 0;
if(GetExitCodeThread(hThread,&dwRet))
{
if(dwRet == STILL_ACTIVE)
bRunning = TRUE;
else
bRunning = FALSE;
return 0;
}
return GetLastError();
}
#include "stdafx.h"
#include "thread.h"
#include <process.h>
//namespace {
// static UINT WINAPI ThreadProc(LPVOID param)
// {
// CThread* thread = reinterpret_cast<CThread*>(param);
// return thread->execute();
// }
//};
CThread::CThread(bool self_delete)
: thread_handle_(INVALID_HANDLE_VALUE)
, thread_id_(0)
, suspended_(false)
, terminated_(false)
, self_delete_(self_delete)
{
memset(thread_info_, 0, sizeof(thread_info_));
}
CThread::~CThread()
{
/* 结束时要停止线程 */
HANDLE h = (HANDLE)::InterlockedExchange((PLONG)&thread_handle_, (LONG)INVALID_HANDLE_VALUE);
if (h!=INVALID_HANDLE_VALUE) {
if (WAIT_OBJECT_0!=::WaitForSingleObject(h, 0)) {
::TerminateThread(h, -8008);
}
}
thread_id_ = 0;
}
DWORD CThread::wait_for(DWORD ms)
{
return ::WaitForSingleObject(thread_handle_, ms);
}
bool CThread::start_thread(bool suspended)
{
on_init();
/* 开启线程 */
assert(thread_handle_==INVALID_HANDLE_VALUE);
suspended = suspended;
thread_handle_ = (HANDLE)_beginthreadex(
NULL,
0,
ThreadProc,
(void*)this,
suspended ? CREATE_SUSPENDED : 0,
&thread_id_
);
if (thread_handle_==INVALID_HANDLE_VALUE)
return FALSE;
on_start();
return TRUE;
}
bool CThread::stop_thread(DWORD ms)
{
/* 不能蛇咬尾巴 */
assert(::GetCurrentThreadId()!=thread_id_);
/* 首先要进行停止操作,否则resume之后,线程得到时间,就又被suspend了! */
terminated_ = true;
/* 停止之前先恢复一下 */
resume_thread();
/* 每次stop一次即可 */
HANDLE h = (HANDLE)::InterlockedExchange((PLONG)&thread_handle_, (LONG)INVALID_HANDLE_VALUE);
if (h==INVALID_HANDLE_VALUE) {
LOG__("[message] close thread but handle invalid.");
return false;
}
/* 注意如果外界调用stop的话,自动取消self_delete模式,否则内存冲突 */
self_delete_ = false;
if (WAIT_OBJECT_0!=::WaitForSingleObject(h, ms)) {
/* 线程没有结束,那么就等待 */
on_stop(true);
::TerminateThread(h, -8888);
} else {
on_stop(false);
}
/* 清除相关数据 */
thread_id_ = 0;
memset(thread_info_, 0, sizeof(thread_info_));
CloseHandle(h);
return true;
}
DWORD CThread::suspend_thread()
{
return SuspendThread(thread_handle_);
}
DWORD CThread::resume_thread(bool all)
{
/* 注意线程唤醒这些是需要计数器的 */
DWORD ticks = -1;
for (;;) {
ticks = ResumeThread(thread_handle_);
if (ticks==-1)
break;
if (!all)
break;
if (ticks>0)
continue;
else
break;
}
return ticks;
}
bool CThread::is_valid()
{
return (thread_handle_==INVALID_HANDLE_VALUE) ? FALSE : TRUE;
}
/* 得到线程句柄 */
HANDLE CThread::get_handle()
{
return thread_handle_;
}
/* 得到线程编号 */
DWORD CThread::get_threadid()
{
return thread_id_;
}
void CThread::set_threadinfo(LPCTSTR info)
{
_tcsncpy(thread_info_, info, sizeof(thread_info_)-1);
}
LPCTSTR CThread::get_threadinfo()
{
return thread_info_;
}
void CThread::set_autodelete(bool del)
{
self_delete_ = del;
}
bool CThread::get_autodelete()
{
return self_delete_;
}
void CThread::set_terminate()
{
terminated_ = true;
}
UINT CThread::execute()
{
// 一个线程的意外不应该影响整个进程,所以这里try住了
int retcode = 0;
/////////////////////////////////////////////////////
MY_TRY_BEGIN
retcode = on_execute();
MY_CATCH_ALL
retcode = 8005;
on_exception();
MY_CATCH_END
/////////////////////////////////////////////////////
/* 线程运行完毕 */
on_runover();
/* 清除自己的内存 */
HANDLE h = (HANDLE)::InterlockedExchange((PLONG)&thread_handle_, (LONG)INVALID_HANDLE_VALUE);
if (h!=INVALID_HANDLE_VALUE) {
memset(thread_info_, 0, sizeof(thread_info_));
::CloseHandle(h);
/* 如果线程是自删除的,删除自己 */
if (self_delete_) {
delete this;
}
}
return retcode;
}
UINT CThread::on_execute()
{
return -8806;
}
strncpy(m_szThreadName, ThreadName, min(strlen(ThreadName), sizeof(m_szThreadName) - 1));