跨windows和linux的线程类

//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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值