C++ Thread class

/*

 * Thread that support cross platform and support global and local start routine, and support 

 * Windows api and C Run-Time Library(even extension) on windows. 

 * <p>

 * To implements a simple thread, only to overrides the run method.

 *

 * @author ada

 * @version 1.0

 * @since 1.0

 */

#include <windows.h>

#if defined(_WIN32) && defined(_MT)

#include <process.h>

#endif

#include "Runnable.hpp"

 

#if ! defined THREAD

#define THREAD

 

// GLOBAL_START_ROUTINE is a user defined macro, likes a switch, to determine whether to 

// select global thread start routine or not. GLOBAL_START_ROUTINE can be defined in program, 

// or using compiler preprocessor options(PREPROCESSOR) /D to define user defined macro 

// GLOBAL_START_ROUTINE to compiles global start routine edition of Thread

#if defined GLOBAL_START_ROUTINE 

 

#define _GLOBAL_START_ROUTINE

#pragma message ("GLOBAL_START_ROUTINE defined, using global thread start routine.")

 

// windows

#ifdef _WIN32 

// using compiler linking options /MT to compiles C Run-Time Library(_beginthread, _beginthreadex) 

// edition of Thread

#if defined(_MT) && (! defined(_MT_RT_EX))

#pragma message ("Using C Run-Time Library global thread start routine.")

//#error "C Run-Time Library global thread start routine not supported."

void execute(void *args);

typedef void (* LP_CRT_THREAD_START_ROUTINE)(void *args);

 

#elif defined(_MT) && defined(_MT_RT_EX)

#pragma message ("Using C Run-Time Library extension global thread start routine.")

//#error "C Run-Time Library extension global thread start routine not supported."

unsigned __stdcall execute(void *args);

typedef unsigned (__stdcall * LP_CRT_EX_THREAD_START_ROUTINE)(void *args);

 

#else 

DWORD execute(LPVOID args);

#endif

 

// linux

#else

void* execute(void *args);

#endif

 

// User defined macro GLOBAL_START_ROUTINE is not specific

// Compiles global start routine edition of Thread using compiler preprocessor options(PREPROCESSOR) /D 

// to define user defined macro GLOBAL_START_ROUTINE

#else 

 

#pragma message ("GLOBAL_START_ROUTINE not defined, do not using global thread start routine.")

// If GLOBAL_START_ROUTINE not defined, for thread start routine function details, See Thread class 

// declaration when user defined macro defined

#endif

 

/**

 *

 *

 *

 */

class /*TK_API*/ Thread : public Runnable 

{

 

private:

 

#if defined(_WIN32) && defined(_MT)

#ifdef _MT_RT_EX

unsigned threadID;

#else

unsigned long threadID;

#endif

#else

DWORD threadID;

#endif

 

Runnable *target;

 

public:

 

Thread();

 

Thread(const Runnable *runnable);

 

#if ! defined _GLOBAL_START_ROUTINE

// windows

#ifdef _WIN32 

#if defined(_MT) && (! defined(_MT_RT_EX))

#pragma message ("Using C Run-Time Library global thread start routine.")

#error "C Run-Time Library global thread start routine not supported."

#elif defined(_MT) && defined(_MT_RT_EX)

#pragma message ("Using C Run-Time Library extension global thread start routine.")

#error "C Run-Time Library extension global thread start routine not supported."

#else 

static DWORD execute(LPVOID args);

#endif

// linux

#else

static void* execute(void *args);

#endif

#endif

 

void start();

 

virtual void run();

 

};

 

#endif

 

======================================================================

 

/*

 *

 *

 * @AUTHOR ADA

 * @VERSION 1.0

 * @SINCE 1.0

 */

#include <stdio.h>

#include <stdlib.h>

#include <string>

#include <windows.h>

#include <log.h>

#include "Thread.hpp"

 

//#define _MT

using namespace std;

 

#if ! defined _GLOBAL_START_ROUTINE 

DWORD Thread::execute(LPVOID args)

{

Thread* t = (Thread *) args;

    t->run();

return 1;

}

#else 

#if defined(_MT) && (! defined(_MT_RT_EX))

void execute(void *args)

{

debug("start routine defined(_MT) && (! defined(_MT_RT_EX))");

Thread* t = (Thread *) args;

    t->run();

}

#elif defined(_MT) && defined(_MT_RT_EX)

unsigned __stdcall execute(void *args)

{

debug("start routine defined(_MT) && defined(_MT_RT_EX)");

Thread* t = (Thread *) args;

    t->run();

return 0;

}

#else

DWORD execute(LPVOID args) 

{

Thread* t = (Thread *) args;

    t->run();

return 1;

}

#endif

#endif

 

/**

 *

 *

 *

 */

Thread::Thread() 

{

    this->threadID = 0;

this->target = NULL;

}

 

Thread::Thread(const Runnable *runnable)

{

this->threadID = 0;

this->target = (Runnable *) runnable;

}

 

void Thread::start() 

{

#if defined(_MT) && (! defined(_MT_RT_EX))

#ifndef _GLOBAL_START_ROUTINE

LP_CRT_THREAD_START_ROUTINE startRoutine = (LP_CRT_THREAD_START_ROUTINE) Thread::execute;

printf("GLOBAL_START_ROUTINE not defined, do not using global thread start routine\n");

#else

LP_CRT_THREAD_START_ROUTINE startRoutine = (LP_CRT_THREAD_START_ROUTINE) execute;

printf("GLOBAL_START_ROUTINE defined, using global thread start routine\n");

#endif

 

#elif defined(_MT) && defined(_MT_RT_EX)

#ifndef _GLOBAL_START_ROUTINE

LP_CRT_EX_THREAD_START_ROUTINE startRoutine = (LP_CRT_EX_THREAD_START_ROUTINE) Thread::execute;

printf("GLOBAL_START_ROUTINE not defined, do not using global thread start routine\n");

#else

LP_CRT_EX_THREAD_START_ROUTINE startRoutine = (LP_CRT_EX_THREAD_START_ROUTINE) execute;

printf("GLOBAL_START_ROUTINE defined, using global thread start routine\n");

#endif

 

#else

#ifndef _GLOBAL_START_ROUTINE

LPTHREAD_START_ROUTINE startRoutine = (LPTHREAD_START_ROUTINE) Thread::execute;

printf("GLOBAL_START_ROUTINE not defined, do not using global thread start routine\n");

#else

LPTHREAD_START_ROUTINE startRoutine = (LPTHREAD_START_ROUTINE) execute;

printf("GLOBAL_START_ROUTINE defined, using global thread start routine\n");

#endif

#endif

 

#if defined(_MT) && (! defined(_MT_RT_EX))

debug("begin thread through _beginthread()");

threadID = _beginthread(startRoutine, 

0, 

(void *) this);

#elif defined(_MT) && defined(_MT_RT_EX)

debug("begin thread through _beginthreadex()");

threadID =  _beginthreadex(NULL, 0, startRoutine, (void *) this, 0, &(this->threadID));

#else

::CreateThread(NULL, 0, startRoutine, (LPVOID) this, 0, &(this->threadID));

#endif

 

debug("Thread %d started", this->threadID);

}

 

void Thread::run() 

{

if (target != NULL) 

{

   target->run();

}

else 

{

debug("Thread::run()");

}

 

}

 

你可能感兴趣的:(thread)