目的:全当语法练习,功能不强大,安全不高,使用较为方便(在需要支持多线程的类继承一下,start一下.就好了.
类的设计:
线程基类:c_thread:
只需要在需要时用的地方继承它,然后实现run,再调用start开始线程class c_thread { public: c_thread(); void start();//开始线程 void wait(int msecond=-1)//等待线程结束 //线程运行(由线程调用,由子类实现) virtual void run()=0; //线程结束(由线程调用) virtual int close(); };
win下的实现代码:
//线程类,功能无需强大,但须特别简单 //使用方法,继承c_thread类,然后实现run函数,调用start,则开辟一个线程 class c_thread { public: DWORD id; HANDLE hthread; c_thread() { id=0; } //开始线程 void start() { //event = CreateEvent (NULL, FALSE, FALSE, NULL); hthread=CreateThread(NULL,0,thread,(LPVOID)this,0,&id); } void wait(int msecond=-1) { if(hthread!=0) ::WaitForSingleObject(hthread,msecond); } //线程运行(由线程调用,由子类实现) virtual void run()=0; //线程结束(由线程调用) virtual int close() { return 0; } private: static DWORD WINAPI thread(LPVOID lparam) { c_thread * p=(c_thread *)lparam; p->run(); int res=p->close(); return res; } };
细节就不多废话了,baidu上很多很多 .使用事例:
class test_thread:public c_thread { public: void run() { int i=20; while(i--) { std::cout<<"hello "<<i<<std::endl; Sleep(100); } } int close() { std::cout<<"close\n"; return 1; } }; int main(int argc, char* argv[]) { test_thread thread; thread.start(); thread.wait(); return 0; }
很好,现在我可以轻易地就获得一个线程,来处理东西了。比如,某个mfc程序的某个对话框中,我需要一个线程来处理数据,比如拷贝文件。就类似这样:
在声明中
class CMfc_theadDlg : public CDialog,public c_mthread
在实现中
void CMfc_theadDlg::run() { ... ... }
好了,垃圾应用到此为止了。
多次start会创建多个线程,且前面创建的线程的handle会丢失。
如果我有个类需要启动多个线程呢?不会是要我创建N个类?类的责职单一性是相当重要的,但我非要呢?
这就是下面的称之为c_mthread类的诞生了
一样,先给个接口声明:
typedef void (c_thread::*THREAD_BACK)(); class c_mthread:public c_thread { public: //开始线程 void start(THREAD_BACK back);//开始一个线程; void wait(int msecond=-1);//等待所有线程结束 ; };
呀,出乎意料,怎么变少了。如何使用呢?当然继承一下,然后start((THREAD_BACK)函数名);
win下的实现:
基本思路是使用函数指针,废话不多说,上代码(马农呀马农,除了代码啥都没有了,其实我连马农都不算,起码他们已经开始耕耘了,我还在田边呢)
class c_single_thread:public c_thread { public: c_thread * point; THREAD_BACK back; c_single_thread() { point=NULL; back=NULL; } void run() { if(point!=NULL && back!=NULL) { (point->*back)(); } } int close() { point=NULL; back=NULL; return 0; } }; class c_mthread:public c_thread { public: vector<c_single_thread*> mthreads; ~c_mthread() { int i=0; for(i=0; i<mthreads.size();i++) { delete mthreads[i]; } mthreads.clear(); } void run() { } //开始线程 void start(THREAD_BACK back) { int i=0; for(i=0; i<mthreads.size();i++) { if(mthreads[i]->point==NULL) { break; } } c_single_thread *p; if(i<mthreads.size()) { p=mthreads[i]; }else { p = new c_single_thread; mthreads.push_back(p); } p->point=this; p->back=(THREAD_BACK)back; p->start(); } void wait(int msecond=-1) { int i=0; for(i=0; i<mthreads.size(); i++) { if(mthreads[i]->point) mthreads[i]->wait(); } } };
就这样,上一个比较长一点的使用用例:class test_mthread:public c_mthread { public: c_mutex mutex; c_event event_a; c_event event_b; void thread1() { while(1) { mutex.lock(); printf("1\n"); Sleep(1000); mutex.unlock(); } } void thread2() { while(1) { mutex.lock(); printf("2\n"); Sleep(100); mutex.unlock(); } } void thread3() { event_b.set(); while(1) { event_a.wait(); printf("3\n"); event_b.set(); Sleep(1000); } } void thread4() { while(1) { event_b.wait(); printf("4\n"); event_a.set(); Sleep(100); } } void begin() { //start((THREAD_BACK)thread1); //start((THREAD_BACK)thread2); start((THREAD_BACK)thread3); start((THREAD_BACK)thread4); } }; int main(int argc, char* argv[]) { test_mthread mthread; mthread.begin(); mthread.wait(); return 0; }
哪来的c_mutex 和 c_event ??
这两个当然不是什么神圣物件,就是一个互斥和一个事件.但他们也不是外来物,自然还是我这里产出的.也是我为了多线程的简洁性而写的两个类.
class c_mutex { public: bool lock(int msecond=-1); bool unlock(); };
class c_event { public: bool wait(int msecond=-1);//等待事件发生; bool set();//设置事件发生; };
好了,废话那么多了,实现如下:
class c_mutex { public: HANDLE mutex; c_mutex() { mutex=::CreateMutex(NULL,false,NULL);//::WaitForSingleObject( } //成功返回1,失败返回0 bool lock(int msecond=-1) { return ::WaitForSingleObject(mutex,msecond)==WAIT_OBJECT_0; } bool unlock() { return ReleaseMutex(mutex)!=0; } ~c_mutex() { ::CloseHandle(mutex); } }; class c_event { public: HANDLE event; c_event() { event=CreateEvent (NULL, FALSE, FALSE, NULL);//::WaitForSingleObject( } //成功返回1,失败返回0 bool wait(int msecond=-1) { return ::WaitForSingleObject(event,msecond)==WAIT_OBJECT_0; } bool set() { return ::SetEvent(event)!=0; } ~c_event() { ::CloseHandle(event); } };
好了练习完毕,噢噢,发现了,还少了个信号量,咯咯,偷懒不写了。等有心人写完送给我。