简单的C++线程操作的封装,使用了智能指针管理对象的释放。
可运行对象基类
class SimpleRunable:public RefCountedBase { public: SimpleRunable(){} virtual ~SimpleRunable(){}//必须为虚析构函数否则,子类析构函数无法调用 virtual void OnRun()=0;//由线程调用 };
实现SimpleRunable的OnRun就可以交由SimpleThread运行。
多线程类封装
class SimpleThread { public: SimpleThread(void); ~SimpleThread(void); bool Start(RefCountedPtr<SimpleRunable> runable);//创建线程 bool Stop(); //强制关闭线程,不建议使用 bool IsRunning(); //判断是否运行 RefCountedPtr<SimpleRunable> GetRunable();//获取当前可运行任务 HANDLE GetHandle(); //获取线程句柄 DWORD GetId(); // 获取线程id private: //禁止赋值构造 SimpleThread(const SimpleThread&); const SimpleThread& operator=(const SimpleThread&); static void ThreadProc(void* param); struct ThreadData* m_data; };
使用方法如下:
class TestRunable:public SimpleRunable { public: void OnRun() { for( int i=0;i<100;++i) { printf("t%d\t",i); } } ~TestRunable() { printf("destroy TestRunable\n"); } }; static void TestSimpleThread() { SimpleThread thread; CountedPtr<SimpleRunable> runable(new TestRunable); thread.Start(runable);Sleep(100); }
SimpleThread类的实现如下:
struct ThreadData { ThreadData():m_isRunning(false),m_handle(NULL),m_count(1)//m_count默认值为1,由SimpleThread所拥有 {} ~ThreadData() { } bool m_isRunning; HANDLE m_handle; int m_count;//计数 RefCountedPtr<SimpleRunable> m_runable; }; SimpleThread::SimpleThread(void):m_data(new ThreadData) { } SimpleThread::~SimpleThread(void) { if (AtomicOps::Decrement(&m_data->m_count)==0) { delete m_data; } } bool SimpleThread::Start(RefCountedPtr<SimpleRunable> runable) { //如果正在运行返回false if (m_data->m_isRunning) { return false; } m_data->m_runable=runable; AtomicOps::Increment(&m_data->m_count);//该计数由ThreadProc减1 HANDLE handle=(HANDLE)_beginthread(ThreadProc,0,m_data); m_data->m_handle=handle; if (!handle) { AtomicOps::Decrement(&m_data->m_count);//线程创建失败计数减一 return false; } else { m_data->m_isRunning=true; return true; } } bool SimpleThread::IsRunning() { return m_data->m_isRunning; } RefCountedPtr<SimpleRunable> SimpleThread::GetRunable() { return m_data->m_runable; } HANDLE SimpleThread::GetHandle() { if (IsRunning()) return m_data->m_handle; else return NULL; } DWORD SimpleThread::GetId() { HANDLE handle=GetHandle(); if(handle) return GetThreadId(handle); else return 0; } bool SimpleThread::Stop() { if (m_data->m_isRunning) { return CloseHandle(m_data->m_handle)==TRUE; } else return false; } void SimpleThread::ThreadProc(void* param) { ThreadData* data=(ThreadData*)param; RefCountedPtr<SimpleRunable>& runable=data->m_runable; if (runable) { runable->OnRun(); } data->m_isRunning=false; if(AtomicOps::Decrement(&data->m_count)==0) delete data; _endthread(); }