您的位置:首页 > 运维架构 > Linux

跨windows和linux的线程类

2016-01-26 08:46 302 查看
//Thread.h

#ifndef _THREAD_H_
#define _THREAD_H_

#ifdef _WIN32
#	include <windows.h>
#	include <process.h>
#else
#	include <pthread.h>
#endif

//可运行基类
class IRunable {
public:
//构造函数
IRunable() {}

//析构函数
virtual ~IRunable() {}

//线程运行入口
virtual void run() = 0;

};

typedef unsigned int ThreadId;

class Thread : public IRunable {
public:
Thread();

/**
* @param target 线程运行目标
* @param release 目标对象是否由线程对象释放
*/
Thread(IRunable& target, bool release = true);

virtual ~Thread();

void start();

virtual void run();

void join();

void detach();

ThreadId getThreadId() const;

bool operator == (const Thread& rhs) const;

bool operator != (const Thread& rhs) const;

bool operator < (const Thread& rhs) const;

public:
static void start(IRunable& target);

static void sleep(int millis);

static ThreadId getCurrentThreadId();

static void yield();

private:
IRunable* _target;

bool _release;

#ifdef _WIN32
ThreadId _threadId;
HANDLE _pThread;
#else
pthread_t _pThread;
#endif
};

#endif //_THREAD_H_

//Thread.cpp

#include "Thread.h"

#ifdef _WIN32
#	include <process.h>
#endif

#include <iostream>

#include <exception>

using std::exception;

//线程运行入口
#ifdef _WIN32
unsigned int _stdcall
#else
void*
#endif
runEntry(void* target) {
try{
reinterpret_cast<IRunable*>(target)->run();
} catch(const exception& ex) {
std::cerr << ex.what() << std::endl;
} catch(...){
std::cerr << "run error" << std::endl;
}
return 0;
}

Thread::Thread() : _target(NULL), _release(false), _pThread(0) {
#ifdef _WIN32
_threadId = 0;
_pThread = INVALID_HANDLE_VALUE;
#else
_pThread = 0;
#endif
}

Thread::Thread(IRunable& target, bool release) : _target(&target), _release(release), _pThread(0) {
#ifdef _WIN32
_threadId = 0;
_pThread = INVALID_HANDLE_VALUE;
#else
_pThread = 0;
#endif
}

Thread::~Thread() {
if(_release)
delete _target;
}

//线程入口
void Thread::run() {}

void Thread::start() {
IRunable* target = _target ? _target : this;

#ifdef _WIN32
_pThread = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, runEntry, target, 0, &_threadId));
if(0 == _pThread) {
throw exception();//GetLastError()
}
#else
pthread_attr_t attr;
int rc = pthread_attr_init(&attr);
if(rc) {
throw exception();//errno
}

rc = pthread_create(&_pThread, &attr, runEntry, target);
if(rc) {
throw exception();//errno
}
#endif
}

void Thread::join() {

#ifdef _WIN32
if(_pThread && WaitForSingleObject(_pThread, INFINITE) != WAIT_OBJECT_0){
throw exception();//GetLastError()
}

detach();
#else
if(_pThread && pthread_join(_pThread, NULL) != 0) {
throw exception();//errno
}
#endif
}

void Thread::detach() {
#ifdef _WIN32
if(_pThread && CloseHandle(_pThread) == 0){
throw exception();//GetLastError()
}
#else
if(_pThread && pthread_detach(_pThread) != 0){
throw exception();//errno
}
#endif
}

ThreadId Thread::getThreadId() const {
#ifdef _WIN32
return _threadId;
#else
return _pThread;
#endif
}

bool Thread::operator == (const Thread& rhs) const {
return this == &rhs;
}

bool Thread::operator != (const Thread& rhs) const {
return this != &rhs;
}

bool Thread::operator < (const Thread& rhs) const {
return this < &rhs;
}

// static functions
void Thread::start(IRunable& target) {
Thread t(target, false);
t.start();
t.detach();
}

void Thread::sleep(int ms) {
#ifdef _WIN32
Sleep(ms);
#else
struct timespec ts;
ts.tv_sec = ms / 1000;
ts.tv_nsec = (ms % 1000) * 1000000;
nanosleep(&ts, 0);
#endif
}

ThreadId Thread::getCurrentThreadId() {
#ifdef _WIN32
return GetCurrentThreadId();
#else
return pthread_self();
#endif
}

void Thread::yield() {
#ifdef _WIN32
Sleep(0);
#else
sched_yield();
#endif
}

//main.cpp

#include "Thread.h"
#include <iostream>

class TestThread : public Thread {
public:
virtual void run() {
std::cout << "this is a thread test" << std::endl;
std::cout << Thread::getCurrentThreadId() << std::endl;
}
};

int main(int argc, char const *argv[])
{
TestThread test;
test.start();
//test.detach();
test.join();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线程