跨平台开发有许多问题要解决,为了方便,通常需要将不同平台的相同功能做封装,以期提供统一的接口供上层调用,这种平台差异的封装意味着更多的代码和更不友好的维护性。线程就是如此,而C++11在语言层面上对线程提供了支持,今天就把之前的线程实现改成了C++11的方式,代码大大简化。
之前的Windows平台线程封装:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class Thread { DISALLOW_COPY_AND_ASSIGN(Thread)
public: Thread();
virtual ~Thread();
public: void Run();
void Wait();
int GetThreadId() const { return static_cast<int>(m_threadId); }
int SetThreadId(int threadId) { m_threadId = static_cast<DWORD>(threadId); }
protected: virtual void Execute() = 0;
private: static unsigned int __stdcall ThreadFunc(void* arg);
private: HANDLE m_hThread; DWORD m_threadId; };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| Thread::Thread() : m_hThread(0) , m_threadId(0) {}
Thread::~Thread() { if (0 != m_threadId) { Wait(); } } void Thread::Run() { unsigned int threadId = 0; uintptr_t ret = ::_beginthreadex(nullptr , 0 , ThreadFunc , this , 0 , &threadId); m_hThread = reinterpret_cast<HANDLE>(ret); m_threadId = threadId; }
void Thread::Wait() { if (0 != m_threadId) { ::WaitForSingleObject(m_hThread, INFINITE); ::CloseHandle(m_hThread); m_threadId = 0; } }
unsigned int __stdcall Thread::ThreadFunc(void* arg) { Thread* thread = static_cast<Thread*>(arg); thread->Execute(); return 0; }
|
之前的Linux平台线程封装:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Thread { DISALLOW_COPY_AND_ASSIGN(Thread)
public: Thread();
virtual ~Thread();
public: void Run();
void Wait();
int GetThreadId() const { return static_cast<int>(m_threadId); }
void SetThreadId(int threadId) { m_threadId = static_cast<pthread_t>(threadId); }
protected: virtual void Execute() = 0;
private: static void* ThreadFunc(void* arg);
private: pthread_t m_threadId; };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| Thread::Thread() : m_threadId(0) {}
Thread::~Thread() { if (0 != m_threadId) { Wait(); } }
void Thread::Run() { const int ret = ::pthread_create(&m_threadId , nullptr , ThreadFunc , this); ASSERT_TRUE(0 == ret); }
void Thread::Wait() { if (0 != m_threadId) { void* status = nullptr; const int ret = ::pthread_join(m_threadId, &status); ASSERT_TRUE(0 == ret); m_threadId = 0; } }
void* Thread::ThreadFunc(void* arg) { Thread* thread = static_cast<Thread*>(arg); thread->Execute(); return nullptr; }
|
C++11版的线程实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Thread { DISALLOW_COPY_AND_ASSIGN(Thread)
public: Thread();
virtual ~Thread();
public: void Run();
void Wait();
void Detach();
std::thread::id GetThreadId() const;
protected: virtual void Execute() = 0;
private: void ThreadFunc();
private: std::thread m_thread; };
inline std::thread::id Thread::GetThreadId() const { return m_thread.get_id(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| Thread::Thread() {}
Thread::~Thread() {}
void Thread::Run() { m_thread = std::thread(std::bind(Thread::ThreadFunc, this)); }
void Thread::Wait() { if (m_thread.joinable()) { m_thread.join(); } }
void Thread::Detach() { m_thread.detach(); }
void Thread::ThreadFunc() { Execute(); }
|