线程和线程池的准备
基于Windows环境下的Microsoft Visual Studio的MSVC编译器的运行时库来实现线程池
当然也可以使用封装好的C++11的线程库,我这里并没有这样做,想着更好的手动控制线程的启动关闭等等的接口的尝试。
class ThreadFunctionBase {};
typedef int (ThreadFunctionBase::* FUNCTYPE)();//定义了一个类型别名FUNCTYPE,是ThreadFunctionBase类内的函数指针
class ThreadWorker {
public:
ThreadWorker() :thiz(NULL),func(NULL) {}
ThreadWorker(ThreadFunctionBase* obj, FUNCTYPE f):thiz(obj),func(f) {}
ThreadWorker(const ThreadWorker& worker){
thiz = worker.thiz;
func = worker.func;
}
ThreadWorker& operator=(const ThreadWorker& worker){
if (this != &worker) {
thiz = worker.thiz;
func = worker.func;
}
return *this;
}
int operator()(){
if (IsValid()) {
return (thiz->*func)();//执行函数
}
return -1;
}
bool IsValid() {
return (thiz != NULL) && (func != NULL);
}
private:
ThreadFunctionBase* thiz;
FUNCTYPE func;
};
class SyqThread {
public:
SyqThread() { m_hThread = NULL; }
bool Start() {
m_bStatus = true;
m_hThread = (HANDLE)_beginthread(&SyqThread::ThreadEntry, 0, this);//创建线程
if (!IsValid) { m_bStatus = false; }
return m_bStatus;
}
bool Stop() {
if (m_bStatus == false) return true;
m_bStatus = false;
return WaitForSingleObject(m_hThread, INFINITY) == WAIT_OBJECT_0;
}
bool IsValid() { //true有效,false无效
if (m_hThread == NULL || (m_hThread == INVALID_HANDLE_VALUE)) return false;
return WaitForSingleObject(m_hThread, 0) == WAIT_TIMEOUT;
}
void UpdateWorker(const ThreadWorker& worker = ThreadWorker()) {
m_worker.store(worker);
}
bool IsIdle() {
//是否是空闲
return !m_worker.load().IsValid();
}
~SyqThread() { Stop(); }
private:
static void ThreadEntry(void* arg) {//线程入口
SyqThread* thiz = (SyqThread*)arg;
if (thiz) {
thiz->ThreadWork();
}
_endthread();
}
virtual void ThreadWork() {
while (m_bStatus) {
ThreadWorker worker = m_worker.load();
if (worker.IsValid()) {
int ret = worker();
if (ret != 0) {
CString str;
str.Format(_T("thread found warning code : %d\r\n"), ret);
OutputDebugString(str);
}
if (ret < 0) m_worker.store(ThreadWorker());
}
else Sleep(1);
}
}
private:
HANDLE m_hThread;
bool m_bStatus;//0fasle将要关闭,1ture正在运行
std::atomic<ThreadWorker> m_worker;//创建一个线程安全的线程工作者
};
class ThreadPool {
public:
ThreadPool(){}
ThreadPool(size_t size) { m_threads.resize(size); }//初始化size个syqThread
bool Invoke() {
bool ret = true;
for (size_t i = 0; i < m_threads.size(); i++) {
if (m_threads[i].Start() == false) {
ret = false;//如果创建失败
break;
}
}//线程池要么全部启动要么全部关闭
if (ret == false) {
for (size_t i = 0; i < m_threads.size(); i++) {
m_threads[i].Stop();
}
}
return ret;
}
void Stop() {
for (size_t i = 0; i < m_threads.size(); i++) {
m_threads[i].Stop();
}
}
int DispatchWorker(const ThreadWorker& worker) {//可以优化链表,查看size在去
int index = -1;
m_mtx.lock();
for (size_t i = 0; i < m_threads.size(); i++) {
if (m_threads[i].IsIdle())//轮询
{
m_threads[i].UpdateWorker(worker);//更新工作者给空闲线程
index = i;
break;
}
}
m_mtx.unlock();
return index;
}
bool CheckThreadValid(int index) {
if (index > 0 && index < m_threads.size()) {
return m_threads[index].IsValid();
}
return false;
}
~ThreadPool() { Stop(); m_threads.clear(); }
private:
std::vector<SyqThread> m_threads;//
std::mutex m_mtx;
};
TEST
class TEST : public ThreadFunctionBase
{
public:
//基本的构造析构...(假装我实现了)
bool test(){
m_pool.Invoke();//线程池启动,后续要在合适的地方释放
m_pool.DispatchWorker(ThreadWorker(this,(FUNCTYPE)&TEST::print));
}
int print(){ cout<<"Thread execution successful"; }
private:
ThreadPool m_pool;
};
大致流程
- 创建线程要执行的函数基类ThreadFunctionBase
- 创建好线程工作者ThreadWorker,作为执行起来的中间者
- 创建好可以手动操作线程的线程类
- 创建好线程池。连结起来:线程—worker—函数
TODO:基于C++11的线程池实现