//ThreadHelper.h
/*--License(在这里设置版权或许可等信息)
--自由无限制
*/
/*
\-Version(在这里记录版本等信息)
--1.00
--publish from http://www.loveunix.net(非正式发布)
--V1.00_@2004_??_?? by somebody(a.somebody@gmail.com).
--update@2005_06_01 by someone.
*/
/*
\ brief(在这里做功能简介)
(Wrapper Thread && ThreadPool)
Thread(class)线程包装(线程类/通过非静态类成员函数创建线程等)
ThreadPool(class)线程池
*/
/*
\ misc(在这里添加使用帮助说明或补充其他细节)
VC++ 6.0(Win2k ADS)
GCC(g++) 3.3.2(Red Hat Linux 7.2)
VC++ 7.1(VS 2003.NET)(Win2k ADS)
Compiled good(run ok).
*/
//#include "ThreadHelper.h"
#ifndef _THREAD_HELPER_H__
#define _THREAD_HELPER_H__
#define DEF_THREADHELPER
#if(0)
//class ThreadHelper {};//--null
#endif
//--WIN32
#if !defined(WIN32)
#if defined(_WIN32) || defined(__WIN32) || defined(__WIN32__)
#define WIN32
#endif
#endif
//--LINUX
#if !defined(WIN32) && !defined(LINUX)
#define LINUX
#endif
#if !defined(WIN32) && !defined(LINUX)
#error only Support Win32 or Linux.
#endif
#ifdef WIN32
#include <windows.h>
#include <string.h>
#endif
#ifdef LINUX
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <string.h>
#endif
#ifndef NULL
#define NULL 0
#endif
//--class Declare
class Thread;
class ThreadPool;
//
//--Thread Base class
class ThreadBase { public: typedef void* (ThreadBase::*Entry)(void*); };
typedef ThreadBase::Entry ThreadBaseEntry;
//
template <typename T>
class ThreadTemplate
{
friend class Thread;
friend class ThreadWrapper;
private:
typedef void* (T::*Entry)(void*);
T* pClass; //--Thread Class
void* pData; //--传递给线程的参数
Entry pEntry; //--Thread Entry Ptr
public:
ThreadTemplate<T>()
: pClass(0), pEntry(0), pData(0)
, Result(0)
, handle(0), ThreadId(0)
{};
long Result; //--保存线程返回值
//--保留与系统相关的线程数据
#if defined(WIN32)
//--WIN32
HANDLE handle;
DWORD ThreadId;
#elif defined(LINUX)
//--LINUX
pthread_t ThreadId;
int handle;
#else
#pragma message( "--unsupported--" )
#endif
};
//
typedef ThreadTemplate<ThreadBase> ThreadObject;
typedef ThreadObject* ThreadObjectPtr;
//
//--ThreadWrapper
//--线程包装
class ThreadWrapper
{
friend class Thread;
private:
void __CreateAny();//--null
//--创建线程
//--线程入口(任意类函数)
template<typename T>
ThreadObjectPtr CreateAny(T * pClass, ThreadBaseEntry pEntry, void* pData)
{
ThreadObjectPtr pThread = new ThreadObject;
pThread->pClass = (ThreadBase*)pClass;
pThread->pData = pData;
pThread->pEntry = pEntry;
return CreateWrapper(NULL, NULL, pThread);
}
//--ThreadCreate
//--模板函数
template<typename T>
ThreadObjectPtr ThreadCreate(T* pClass
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
, ThreadTemplate<Thread>::Entry pEntry//--VC7
#else
, ThreadTemplate<T>::Entry pEntry
#endif
, void* pData = NULL
)
{
if (NULL == pClass || NULL == pEntry) return NULL;
//--创建暂存对象(ThreadTemplate<T>/ThreadObject)
//--注意这个对象由(Thread)删除
ThreadTemplate<T> * pObj = new ThreadTemplate<T>;
//--设置参数
pObj->pEntry = pEntry;
pObj->pClass = pClass;
pObj->pData = pData;
//--创建线程
return CreateWrapper(NULL, NULL, pObj);
}
//--EntryWrapper(线程入口)
//--包装线程入口(类函数)
static void EntryWrapper(ThreadObjectPtr pThread)
{
if (NULL == pThread) return;
long Result = 0;
//--这里执行真正的线程代码
Result = (long)(pThread->pClass->*(pThread->pEntry))(pThread->pData);
//--真正的线程代码执行完毕(线程马上退出)
//--Result
pThread->Result = Result;
}
//--EntryEntry(线程入口)
//--包装线程入口(普通函数)
struct EntryData
{
ThreadObjectPtr pThread;//--Result
void* pData;
void* pEntry;
};
static void EntryEntry(EntryData * pEntry)
{
if (NULL == pEntry) return;
long Result = 0;
//--这里执行真正的线程代码
typedef long (*ENTRY)(void*);
ENTRY entry = (ENTRY)pEntry->pEntry;
if (entry) Result = (long)( (*entry)(pEntry->pData) );
//--真正的线程代码执行完毕(线程马上退出)
//--Result
if (NULL != pEntry->pThread) pEntry->pThread->Result = Result;
delete pEntry;
}
//--CreateWrapper(创建并运行线程)
//--以(EntryWrapper)或(EntryEntry)做线程入口
static ThreadObjectPtr CreateWrapper(void* entry, void* pData, void* pObj = NULL);
};
inline
ThreadObjectPtr ThreadWrapper::CreateWrapper(void* entry, void* pData, void* pObj)
{
ThreadObjectPtr pThread = NULL;
EntryData * pEntryData = NULL;
if (NULL == pObj)
{
pThread = new ThreadObject;
pEntryData = new EntryData;
pEntryData->pThread = pThread;
pEntryData->pEntry = entry;
pEntryData->pData = pData;
}
else pThread = ThreadObjectPtr(pObj);
//--在这里调用系统代码
if (NULL != pThread)
{
#ifdef WIN32
//--WIN32
#pragma message( "WIN32 ThreadWrapper::CreateThreadWrapper" )
typedef LPTHREAD_START_ROUTINE ThreadEntry;
pThread->ThreadId = 0;
pThread->handle = NULL;
pThread->handle = CreateThread(NULL, 0
, ( (NULL == pObj)
?( (ThreadEntry)EntryEntry )
:( (ThreadEntry)EntryWrapper ) )
, ( (NULL == pObj)?( (void*)pEntryData):( (void*)pThread) )
, 0, &pThread->ThreadId);
#elif defined(LINUX)
//--LINUX
#pragma message( "LINUX ThreadWrapper::CreateThreadWrapper" )
typedef void* (*ThreadEntry)(void*);
pThread->ThreadId = 0;
pThread->handle = 0;
pThread->handle = pthread_create(&pThread->ThreadId, NULL
, ( (NULL == pObj)
?( (ThreadEntry)EntryEntry )
:( (ThreadEntry)EntryWrapper ) )
, ( (NULL == pObj)?( (void*)pEntryData):( (void*)pThread) )
);
#else
#pragma message( "--unsupported--" )
#endif
}
return pThread;
}
//
//--Thread
//--线程(包装)类(实现通过类非静态成员函数创建线程等)
class Thread
{
public:
//--(线程函数)默认线程入口(类非静态成员函数)
virtual void* ThreadProc(void* pData = NULL) { return 0; };
public:
//--睡眠(ms)毫秒
static void Sleep(int ms);
//--结束线程(强制杀掉线程)
//--成功返回0
int Kill(ThreadObjectPtr pThread = NULL);
//--等待线程(线程结束返回)
//--成功返回0
int Wait(ThreadObjectPtr pThread = NULL);
//--获取线程(ThreadObject)数据
//--返回(ThreadObject/线程数据对象)指针(成功)或0(失败)
inline ThreadObjectPtr GetThread() const { return PtrThreadObject; };
public:
void __CreateAny();//--null
//--Create(创建并运行线程)
//--线程入口 = pEntry
//--pEntry(任意类任意成员函数)
//--要求任意类任意成员函数原型(参数与返回值类型)为[void* (void*)]/不保证其他原型不出错
//--需要参数(tClass)
//--tClass(pEntry宿主类)
//--返回(ThreadObject/线程数据对象)指针
template<typename T>
ThreadObjectPtr Create(T & tClass, ThreadBaseEntry pEntry, void* pData)
{
ThreadWrapper Wrapper;
ThreadInit();
SetThread(
Wrapper.CreateAny(&tClass, pEntry, pData)
);
delay();
return GetThread();
}
public:
//--Create(创建并运行线程)
//--线程入口 = ThreadProc
//--ThreadProc(线程函数)默认线程入口(类非静态成员函数)
//--返回(ThreadObject/线程数据对象)指针
ThreadObjectPtr Create(void* pData)
{
ThreadWrapper Wrapper;
ThreadInit();
SetThread(
Wrapper.ThreadCreate(this
, (ThreadTemplate<Thread>::Entry)&Thread::ThreadProc
, pData)
);
delay();
return GetThread();
}
//--Create(创建并运行线程)
//--线程入口 = entry
//--entry(普通函数/或类静态成员函数)
//--返回(ThreadObject/线程数据对象)指针
ThreadObjectPtr Create(void* entry, void* pData)
{
ThreadWrapper wrapper;
ThreadInit();
SetThread(
wrapper.CreateWrapper(entry, pData)
);
delay();
return GetThread();
}
public:
Thread() : PtrThreadObject(NULL) {};
virtual ~Thread() { ThreadInit(); };
//inline ThreadObjectPtr GetThread() const { return PtrThreadObject; };
private:
inline void SetThread(ThreadObjectPtr v) { PtrThreadObject = v; };
//--data
ThreadObjectPtr PtrThreadObject;
//--初始化或结束
void ThreadInit()
{
ThreadObjectRelease(PtrThreadObject);
clear();
}
protected:
void clear() { PtrThreadObject = NULL; };
//--清空并释放(删除)(ThreadObject)对象
void ThreadObjectRelease(ThreadObjectPtr p)
{
if (NULL == p) return;
#if defined(WIN32)
if (p->handle) CloseHandle(p->handle);
#endif
memset(p, 0, sizeof(*p));
delete p;
}
//--通过调用(delay)让当前线程交出控制权
//--阻止当前线程独占资源
//--当前线程会被挂起约一毫秒的时间
static void delay()
{
Thread::Sleep(0);
Thread::Sleep(1);
Thread::Sleep(0);
}
};
inline int Thread::Kill(ThreadObjectPtr pThread)
{
int ret = 0;
const ThreadObjectPtr a = (NULL != pThread)?(pThread):(GetThread());
//--这里调用操作系统相关的代码
if (NULL != a)
{
#if defined(WIN32)
//--WIN32
#pragma message( "WIN32 Thread::Kill" )
HANDLE handle = a->handle;
if (NULL != handle)
{
BOOL b = TerminateThread(handle, 0);
//--FAILED
if (!b) ret = b;
CloseHandle(handle);
a->handle = NULL;
}
#elif defined(LINUX)
//--LINUX
#pragma message( "LINUX Thread::Kill" )
pthread_t ThreadId = a->ThreadId;
if (ThreadId > 0)
{
int n = pthread_cancel(ThreadId);
//--FAILED
if (n) ret = n;
}
#else
#pragma message( "--unsupported--" )
#endif
//Wait(a);
}
return ret;
}
inline int Thread::Wait(ThreadObjectPtr pThread)
{
int ret = 0;
const ThreadObjectPtr a = (NULL != pThread)?(pThread):(GetThread());
//--这里调用操作系统相关的代码
if (NULL != a)
{
#if defined(WIN32)
//--WIN32
#pragma message( "WIN32 Thread::Wait" )
HANDLE handle = a->handle;
if (NULL != handle)
{
DWORD d = WaitForSingleObject(handle, INFINITE);
//--FAILED
if (WAIT_OBJECT_0 != d) ret = d;
if (0 == ret) CloseHandle(handle);
a->handle = NULL;
}
#elif defined(LINUX)
//--LINUX
#pragma message( "LINUX Thread::Wait" )
pthread_t ThreadId = a->ThreadId;
if (ThreadId > 0)
{
int n = pthread_join(ThreadId, NULL);
//--FAILED
if (0 == n) ret = n;
}
#else
#pragma message( "--unsupported--" )
#endif
}
return ret;
}
inline void Thread::Sleep(int ms)
{
#if defined(WIN32)
//--WIN32
#pragma message( "WIN32 Thread::Sleep" )
::Sleep(ms);
#elif defined(LINUX)
//--LINUX
#pragma message( "LINUX Thread::Sleep" )
usleep(ms*1000);
#else
#pragma message( "--unsupported--" )
#endif
}
//--就差线程池了
//
//--ThreadPool
//--线程池
class ThreadPool : public Thread
{
public:
//--启动线程池内线程
//--(n > 0) 时先设置线程数(n)再启动线程池内线程
//--(n <= 512)
void Start(void* pData)
{
if (ThreadNumber <= 0) return;
ThreadArray = (ThreadObjectPtr*)new ThreadObjectPtr[ThreadNumber];
for (int i = 0; i < ThreadNumber; ++i)
{
ThreadArray[i] = Create(pData);
clear();
}
}
void Start(void* entry, void* pData)
{
if (ThreadNumber <= 0) return;
ThreadArray = (ThreadObjectPtr*)new ThreadObjectPtr[ThreadNumber];
for (int i = 0; i < ThreadNumber; ++i)
{
ThreadArray[i] = Create(entry, pData);
clear();
}
}
//--等待线程池内全部线程结束
//--成功返回0
int WaitFor();
//--获取线程池最大线程数
int GetNumber() { return ThreadNumber; };
//--设置线程池最大线程数
void SetNumber(int n)
{
PoolRelease();
//--一下启动太多线程有可能把系统搞死
//--限制一下(512/可以根据需要和系统情况自己设置)
ThreadNumber = (n > 512)?(512):(n);
}
//--获取线程池内第(n)(n >=0 && n < ThreadNumber)个线程
inline ThreadObjectPtr GetThread(int n) const
{
if (NULL == ThreadArray) return NULL;
if (n >= 0 && n < ThreadNumber) return ThreadArray[n];
return NULL;
}
public:
virtual ~ThreadPool() { PoolRelease(); };
ThreadPool(int n = 1)
: ThreadArray(0)
, ThreadNumber(n)
{};
private:
int ThreadNumber;//--保存线程数
ThreadObjectPtr* ThreadArray;//--(内部)线程对象(数组)
//--初始化或结束
//--释放对象(内部)
void PoolRelease()
{
if (NULL == ThreadArray) return;
for (int i = 0; i < ThreadNumber; ++i)
{
if (NULL != ThreadArray[i])
{
ThreadObjectRelease(ThreadArray[i]);
ThreadArray[i] = NULL;
}
}
delete []ThreadArray;
ThreadArray = NULL;
ThreadNumber = 0;
}
};
inline int ThreadPool::WaitFor()
{
int ret = 0;
#if defined(WIN32)
//--WIN32
#pragma message( "WIN32 ThreadPool::WaitFor" )
if (ThreadNumber > 0 && NULL != ThreadArray)
{
if (ThreadNumber <= MAXIMUM_WAIT_OBJECTS)
{
int ii = 0;
HANDLE* lpHandles = new HANDLE[ThreadNumber];
int i = 0;
for (i = 0; i < ThreadNumber; ++i)
{
if (ThreadArray[i]->handle)
lpHandles[ii++] = ThreadArray[i]->handle;
}
DWORD d = WaitForMultipleObjects(ii, lpHandles, TRUE, INFINITE);
if(WAIT_FAILED == d) ret = d;
for (i = 0; i < ii; ++i) CloseHandle(lpHandles[i]);
for (i = 0; i < ThreadNumber; ++i)
{
if (ThreadArray[i]->handle)
ThreadArray[i]->handle = NULL;
}
delete []lpHandles;
}
else
{
int n = MAXIMUM_WAIT_OBJECTS;
int m = ThreadNumber/n;
int t = n;
for (int j = 0; j < m; ++j)
{
int ii = 0;
HANDLE* lpHandles = new HANDLE[t];
int i = 0;
for (i = 0; i < t; ++i)
{
if (ThreadArray[n*j + i]->handle)
lpHandles[ii++] = ThreadArray[n*j + i]->handle;
}
DWORD d = WaitForMultipleObjects(ii, lpHandles, TRUE, INFINITE);
if(WAIT_FAILED == d) ret = d;
for (i = 0; i < ii; ++i) CloseHandle(lpHandles[i]);
for (i = 0; i < t; ++i)
{
if (ThreadArray[n*j + i]->handle)
ThreadArray[n*j + i]->handle = NULL;
}
delete []lpHandles;
}
t = ThreadNumber%n;
if (t > 0)
{
int ii = 0;
HANDLE* lpHandles = new HANDLE[t];
int i = 0;
for (i = 0; i < t; ++i)
{
if (ThreadArray[n*m + i]->handle)
lpHandles[ii++] = ThreadArray[n*m + i]->handle;
}
DWORD d = WaitForMultipleObjects(ii, lpHandles, TRUE, INFINITE);
if(WAIT_FAILED == d) ret = d;
for (i = 0; i < ii; ++i) CloseHandle(lpHandles[i]);
for (i = 0; i < t; ++i)
{
if (ThreadArray[n*m + i]->handle)
ThreadArray[n*m + i]->handle = NULL;
}
delete []lpHandles;
}
}
}
#elif defined(LINUX)
//--LINUX
#pragma message( "LINUX ThreadPool::WaitFor" )
if (ThreadNumber > 0 && NULL != ThreadArray)
{
pthread_t* pHandles = new pthread_t[ThreadNumber];
for (int i = 0; i < ThreadNumber; ++i)
pHandles[i] = ThreadArray[i]->ThreadId;
for(int j = 0; j < ThreadNumber; ++j)
pthread_join(pHandles[j], NULL);
}
#else
#pragma message( "--unsupported--" )
#endif
return ret;
}
//
#endif //--_THREAD_HELPER_H__
http://www.loveunix.net/thread-52904-1-1.html
//--this is only a demo
/*
--test on--
VC++ 6.0(Win2k ADS)
g++ (GCC) 3.3.2(Red Hat Linux 7.2)
VC++ 7.1(VS 2003.NET)(Win2k ADS)
Compiled good(run ok).
*/
#include "ThreadHelper.h"
#include <iostream>
using namespace std;
//
//--普通函数创建线程
//
//--普通函数(abc)
int abc(int n)
{
cout << "::abc" << endl;
for (int i = 0; i < 5; ++i)
{
cout << (1 + i) << endl;
Thread::Sleep(10);
}
cout << "return " << n << endl;
return (n);
}
//--普通函数(abc2)
void abc2()
{
cout << "::abc2" << endl;
}
void Thread_Create()
{
cout << "--go--Thread_Create" << endl;
Thread thread;
//--创建线程
thread.Create((void*)abc, reinterpret_cast<void*>(123) );
ThreadObjectPtr pt = thread.GetThread();
cout << "Result = " << pt->Result << endl;
cout << "Wait()..." << thread.Wait() << endl;//--等待线程结束
cout << "Result = " << pt->Result << endl;
cout << "--ko--Thread_Create" << endl;
}
void Thread_Create2()
{
cout << "--go--Thread_Create2" << endl;
Thread thread;
//--创建线程
thread.Create((void*)abc2, NULL );
ThreadObjectPtr pt = thread.GetThread();
cout << "Result = " << pt->Result << endl;
cout << "Wait()..." << thread.Wait() << endl;//--等待线程结束
cout << "Result = " << pt->Result << endl;
cout << "--ko--Thread_Create2" << endl;
}
//
//--普通类非静态成员函数创建线程
//
//--线程类(A)
//--继承自(Thread)
class A : public Thread
{
//--(线程函数)默认线程入口(类非静态成员函数)
virtual void* ThreadProc(void* pData = NULL)
{
cout << "A::" << endl;
for (int i = 0; i < 5; ++i)
{
cout << (1 + i) << endl;
Sleep(100);
}
return pData;
}
public:
//--(线程函数)任意入口(类非静态成员函数)
void* abc(void* pData = NULL)
{
cout << "A::abc" << endl;
cout << "k = " << k << endl;
for (int i = 0; i < 5; ++i)
{
cout << (1 + i) << endl;
Sleep(100);
}
return pData;
}
void* abc2(void* pData = NULL)
{
cout << "A::abc2" << endl;
cout << "k = " << k << endl;
for (int i = 0; i < 5; ++i)
{
cout << (1 + i) << endl;
Sleep(100);
}
for (int j = 0; j < 5; ++j)
{
cout << (1 + j) << endl;
Sleep(100);
}
return pData;
}
int k;
};
void Thread_A()
{
cout << "--go--Thread_A" << endl;
A a;
A & thread = a;
//--创建线程
a.Create((void*)123);
ThreadObjectPtr pt = thread.GetThread();
cout << "Result = " << pt->Result << endl;
cout << "Wait()..." << thread.Wait() << endl;//--等待线程结束
cout << "Result = " << pt->Result << endl;
cout << "--ko--Thread_A" << endl;
}
void Thread_A2()
{
cout << "--go--Thread_A2" << endl;
A a;
A & thread = a;
//--创建线程
a.k = 111;
a.Create(a, (ThreadBaseEntry)&A::abc, (void*)234);
ThreadObject t1 = *thread.GetThread();
a.k = 123;
a.Create(a, (ThreadBaseEntry)&A::abc2, (void*)100);
ThreadObject t2 = *thread.GetThread();
a.k = 300;
a.Create(a, (ThreadBaseEntry)&A::abc, (void*)258);
ThreadObject t3 = *thread.GetThread();
ThreadObjectPtr pt = thread.GetThread();
cout << "Result = " << pt->Result << endl;
cout << "Wait()..." << thread.Wait() << endl;//--等待线程结束
cout << "Result = " << pt->Result << endl;
cout << "Wait(1)..." << thread.Wait(&t1) << endl;
cout << "Wait(2)..." << thread.Wait(&t2) << endl;
cout << "Wait(3)..." << thread.Wait(&t3) << endl;
cout << "--ko--Thread_A2" << endl;
}
//
//--线程池
//
class B : public ThreadPool
{
virtual void* ThreadProc(void* pData = NULL)
{
cout << "B::" << endl;
for (int i = 0; i < 5; ++i)
{
cout << (1 + i) << endl;
Sleep(100);
}
return pData;
}
public:
};
void ThreadPool_B()
{
cout << "--go--ThreadPool_B" << endl;
B b;
b.SetNumber(3);
b.Start((void*)777);
b.Start(abc, (void*)777);
B & thread = b;
ThreadObjectPtr pt = thread.GetThread(0);
thread.Kill(pt);
cout << "Result = " << pt->Result << endl;
cout << "WaitFor()..." << thread.WaitFor() << endl;
cout << "Result = " << pt->Result << endl;
pt = thread.GetThread(1);
cout << "Result = " << pt->Result << endl;
cout << "--ko--ThreadPool_B" << endl;
}
//
//
int main(int argc, char* argv[])
{
//Thread_Create();
//Thread_Create2();
Thread_A();
Thread_A2();
//ThreadPool_B();
cout << endl;
cout << "wait return ...";
cout << endl;
cin.get();
return 0;
}