SimpleThread class
SimpleThread class for windows.See also:boost::thread and thread class in C++0x
// Copyright (C) 2009, Thiago Adams (thiago.adams@gmail.com) // http://www.thradams.com/codeblog/simplethread.htm // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // namespace Detail { template<class F> class SimpleThreadData0 { F m_f; public: SimpleThreadData0(const F& f) : m_f(f) { } void Run() { m_f(); } }; template<class F, class A1> class SimpleThreadData1 { F m_f; A1 m_a1; public: SimpleThreadData1(const F& f, const A1& a1) : m_f(f), m_a1(a1) { } void Run() { m_f(m_a1); } }; } //namespace Detail class SimpleThread { HANDLE m_hThread; template<class T> static DWORD WINAPI ThreadProc(LPVOID lpParameter) { DWORD r = 0; T *p = reinterpret_cast<T*>(lpParameter); try { p->Run(); } catch (...) { r = 1; } delete p; return r; } template<class T> static HANDLE StartThread(T* p) { HANDLE hThread = CreateThread(NULL, // default security attributes 0, // use default stack size &ThreadProc<T>, // thread function p, // argument to thread function 0, // use default creation flags 0); // returns the thread identifier if (hThread == 0) { DWORD dwError = GetLastError(); delete p; throw std::exception("SimpleThread creation failed"); } //release will be made in the other thread. return hThread; } public: template <class F> SimpleThread(const F& f) : m_hThread(NULL) { m_hThread = StartThread(new Detail::SimpleThreadData0<F>(f)); } template <class F, class A1> SimpleThread(const F& f, const A1& a1) : m_hThread(NULL) { m_hThread = StartThread(new Detail::SimpleThreadData1<F, A1>(f, a1)); } ~SimpleThread() { Join(); } void Join() { ::WaitForSingleObject(m_hThread, INFINITE); CloseHandle(m_hThread); m_hThread = 0; } }; }}} Sample {{{cpp void f(const std::string& } { } int main() { SimpleThread thread3(&f, std::string("test")); } Member functions class X { std::auto_ptr<SimpleThread> m_pThread; public: X() : m_pThread(nullptr) { } void Start() { m_pThread.reset(new SimpleThread(std::tr1::bind(&X::ThreadProc, this))); } void ThreadProc() { cout << "hi!"; } }; }}} Version 2 - Requires tr1::bind avaiable in VC++ 2008 {{{cpp // Copyright (C) 2009, Thiago Adams (thiago.adams@gmail.com) // http://www.thradams.com/codeblog/simplethread.htm // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // class SimpleThread { HANDLE m_hThread; template<class F> struct SimpleThreadData0 { F m_f; SimpleThreadData0(const F& f) : m_f(f) { } }; template<class T> static DWORD WINAPI ThreadProc(LPVOID lpParameter) { DWORD r = 0; T *p = reinterpret_cast<T*>(lpParameter); try { p->m_f(); } catch (...) { r = 1; } delete p; return r; } template <class F> HANDLE SimpleThreadInit(const F& f) { std::auto_ptr<SimpleThreadData0<F> > sp(new SimpleThreadData0<F>(f)); HANDLE hThread = CreateThread(NULL, // default security attributes 0, // use default stack size &ThreadProc<SimpleThreadData0<F> >, // thread function sp.get(), // argument to thread function 0, // use default creation flags 0); // returns the thread identifier if (hThread == 0) { DWORD dwError = GetLastError(); throw std::exception("SimpleThread creation failed"); } sp.release(); return hThread; } public: template <class F> SimpleThread(const F& f) : m_hThread(NULL) { m_hThread = SimpleThreadInit(f); } template <class F, class A1> SimpleThread(const F& f, const A1& a1) : m_hThread(NULL) { m_hThread = SimpleThreadInit(std::tr1::bind(f, a1)); } template <class F, class A1, class A2> SimpleThread(const F& f, const A1& a1, const A2& a2) : m_hThread(NULL) { m_hThread = SimpleThreadInit(std::tr1::bind(f, a1, a2)); } ~SimpleThread() { Join(); } void Join() { ::WaitForSingleObject(m_hThread, INFINITE); CloseHandle(m_hThread); m_hThread = 0; } };
Sample2
class X { std::auto_ptr<SimpleThread> m_pThread; public: X() : m_pThread(nullptr) { } void Start() { //no need for manual bind here m_pThread.reset(new SimpleThread(&X::ThreadProc, this, "start")); } void ThreadProc(const std::string& s) { std::cout << "hi!" << s; } };