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>

#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.")

 

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

 

#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 *arg);

 

#else 

DWORD execute(LPVOID args);

#endif

 

#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:

 

DWORD threadID;

 

Runnable *target;

 

public:

 

Thread();

 

Thread(const Runnable *runnable);

 

#if ! defined _GLOBAL_START_ROUTINE

#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

#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)

{

Thread* t = (Thread *) args;

    t->run();

}

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

unsigned __stdcall execute(void *arg)

{

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() 

{

#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

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

 

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

}

 

void Thread::run() 

{

if (target != NULL) 

{

   target->run();

}

else 

{

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

}

}

 

 

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

 

#ifndef _MT

#error "Compiler linking options /MT not specific"

#endif

 

#include <stdio.h>

#include <windows.h>

#include <process.h>

 

#include "../Thread.hpp"

#include "../LinkedLibrary.h"

 

void start_address(void *arg)

{

printf("_beginthread start_address\n");

}

 

unsigned __stdcall start_address_ex(void *arg)

{

printf("_beginthreadex start_address_ex\n");

return 0;

}

 

int main()

{

printf("Thread test\n");

 

#ifdef _MT 

printf("MT defined\n");

#endif

 

unsigned long th;

printf("Thread _beginthread test\n");

th = _beginthread(start_address, 

0, 

NULL);

printf("_beginthread return %ld\n", th);

 

unsigned thread;

// CREATE_SUSPENDED 

th = _beginthreadex(NULL, 0, start_address_ex, NULL, 0, &thread);

 

 

Thread *t = new Thread();

t->start();

 

ExitThread(0);

return 0;

}

 

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

 

DEBUG=../Debug

PATH_VS=D:\usr\bin\Microsoft Visual Studio\VC98

CL="$(PATH_VS)\Bin\cl.exe"

LINK="$(PATH_VS)\Bin\link.exe"

 

INCLUDE="D:\usr\bin\Microsoft Visual Studio\VC98\Include"

LIB="D:\usr\bin\Microsoft Visual Studio\VC98\Lib"

 

INCLUDE_LIB_LOG=D:\home\admin\workstation\c\liblog

LIB_LIB_LOG=D:\home\admin\workstation\c\liblog\Debug

 

INCLUDE_MYSQL=D:\usr\srv\mysql51\include

LIB_MYSQL=D:\usr\srv\mysql51\lib\debug

 

INCLUDE_LUA=D:\usr\bin\Lua\5.1\include

LIB_LUA=D:\usr\bin\Lua\5.1\lib

 

liblog.lib: clean 

 

# using compiler linking options /MT, If compiles _beginthread edition of Thread

$(CL) /GX /W3 /MT /DGLOBAL_START_ROUTINE /I $(INCLUDE) /I $(INCLUDE_LIB_LOG) /c /Fo$(DEBUG)/ ../Thread.cpp

$(CL) /GX /W3 /MT /DGLOBAL_START_ROUTINE /I $(INCLUDE) /c /Fo$(DEBUG)/ ThreadTest__beginthread.cpp

 

$(LINK) /LIBPATH:$(LIB) /LIBPATH:$(LIB_LIB_LOG) /LIBPATH:$(LIB_MYSQL) /LIBPATH:$(LIB_LUA) /OUT:$(DEBUG)/ThreadTest__beginthread.exe $(DEBUG)/*.obj

cp ../liblog.dll $(DEBUG)

clean:

rm -Rf ./*.bak

rm -Rf ./*.o

rm -Rf ./*.obj

rm -Rf ./*.exe

rm -Rf ../Debug/*

 

 

你可能感兴趣的:(thread)