简单模拟boost::thread
本来只想学习asio的,却被boost的强大所吸引,几乎两天都在看boost文档,还好html的比较好看,比起看Intel手册是舒服多了。
boost的thread类可以用任意函数来做线程函数,甚至可以是类的非静态成员函数,并且函数的返回类型和参数都不限(参数个数限制为最多9个)。MFC程序员渴望的用类的非静态成员函数做线程函数用boost::thread得以几乎完美的实现。
下面是个十分简化的模拟boost::thread,主要实现可以用任意函数做线程函数,包括类的非静态成员函数。如下:
#include <iostream> #include <functional> // std::tr1::bind #include <windows.h> class MyThread { private: class ThreadDataBase { public: ThreadDataBase() {} virtual ~ThreadDataBase() {} virtual void Run() = 0; }; // 用于保存线程相关的信息结构,这里只保存了MyThread构造函数 // 时获得的F对象,一般是由bind返回的functor。 // boost::thread类里的这个结构还保存了线程句柄等其它信息 template <typename F> class ThreadData : public ThreadDataBase { private: F f; public: ThreadData(F _f) : f(_f) {} void Run() { f(); // 调用functor } }; // 线程句柄 HANDLE m_hThread; // 因为不知道typename,所以不能定义ThreadData指针,所以建了个 // 空基类,然后利用虚函数的特性调用派生类的Run() ThreadDataBase* pThreadData; // 线程中介函数,内部调用functor static DWORD CALLBACK ThreadProxy(LPVOID lpParam) { ThreadDataBase *pData = reinterpret_cast<ThreadDataBase*>(lpParam); pData->Run(); delete pData; return 0; } public: template <class F> explicit MyThread(F f) : pThreadData(new ThreadData<F>(f)) // 保存好functor { m_hThread = CreateThread(NULL, 0, &ThreadProxy, pThreadData, 0, NULL); } // 类似boost::thread::join() void Wait() { WaitForSingleObject(m_hThread, INFINITE); } }; // 测试类 class Test { public: void TestThread(int nArg1, int nArg2) { std::cout << "Thread in class, Arg1 = " << nArg1 << ", Arg2 = " << nArg2 << std::endl; } }; int main(int argc, char* argv[]) { Test test; // 使用类的非静态成员函数做线程函数 // 而且类成员函数的返回类型和参数都没有限制 MyThread thrd(std::tr1::bind(&Test::TestThread, &test, 123, 321)); thrd.Wait(); return 0; }
这里用了std::tr1库,没用boost,请使用VC++ 2008 SP1编译(据说VC++ 2010已经把std::tr1下的东东移到了std下)。
实现用任意函数做线程函数主要依赖于std::tr1::bind(类似于boost::bind),std::tr1::bind会生成一个可调用的函数对象,
std::tr1::bind(&Test::TestThread, &test, 123, 321)
其实就基本上等于下面的伪代码:
class functor { public: void operator() { (&test)->TestThread(123, 321); } };
所以MyThread::ThreadData::Run里调用的f()实际上就等于调用了functor(),也就间接的调用了(&test)->TestThread(123, 321)。
MyThread里有个静态成员函数ThreadProxy,ThreadProxy内部去调用了构造MyThread时获得的函数,然后返回0,boost::thread里也有这样一个函数,叫thread_start_function。
可以看到用MyThread创建的线程永远返回0(GetExitCodeThread),boost::thread也是这样。为什么这样?可以思考这样一个问题,在Windows上,线程都要求要有一个返回值,但如果传递给boost::thread一个返回void的函数,那线程该返回什么呢?所以通通让它返回0算了。
刚接触boost,上面内容如有错误请高手斧正。

真正的程序员用C++,我以前自学过这个,呵呵!
boost在平时工作中也用的,不过有些小项目,如果把boost编译链接进去,太大了……
你这个代码,用插件显示的么?是什么插件啊?
代码高亮用的是WP-Syntax插件,自己改了点颜色配置。