# Thread Class

Topics

:

Overview
Conditional Directives
Type Definitions
Enumerations
Derived Class Interface
Thread Functions
Pool Functions
Timer Functions

Overview

The gxThread class is an abstract base class used to create platform independent multi-threaded applications. Its object-oriented design utilizes the multiple inheritance features of C++ to allow new or existing classes to directly integrate threading without sacrificing functionality. A derived class must define its own entry function for the operation that will run concurrently. Optionally a derived class can define an exit routine and a cleanup handler to perform any additional operations needed to free thread resources following an exit or cancel call. Refer to the gxThread Model block diagram for an illustration of the base/derived class relationship.

When a new thread is created a gxThread_t object is constructed and will hold a complete set of thread variables that will be available to the derived class through a gxThread_t pointer. Once a thread is created gxThread_t objects can be operated on independently of the base/derived class relationship. The gives the application the ability to control threads generated by any number of classes within the application. Additionally applications can use the built-in thread pool features of the gxThread class to group related and unrelated threads within a process together.

Applications built using the gxThread library should focus on the following modules:

thrtype.h - Type definitions used throughout the library
gxthread.h - Abstract gxThread base class
gthreadt.h - gxThread_t thread variable class
gxmutex.h - Mutal exclusion synchronization class
gxcond.h - Conditional variable synchronization class
gxsema.h - Semaphore synchronization class

All the other low-level wrappers are transparent to the application and are not intended for direct use.

Conditional Directives

In order to achieve cross-platform interoperability conditional directives are used by the low-level thread API wrapper classes to identify the correct thread API call for the each specific platform. The correct directive for your specific platform must be defined using the "-D" compiler option or from within your IDE. The following is a complete listing of all the conditional directives used in the gxThread library:

Windows 95/98/NT/2000 Directives

:

__WIN32__

WIN32 directive for Windows 95/98/NT/2000 applications.

__HAS__BEGINTHREADEX__

Create thread using the _beginthreadex() C RTL call.

UNIX Directives

:

__UNIX__

Generic UNIX directive. NOTE: This directive must be defined for all UNIX systems.

__POSIX__

Define for applications using any version of POSIX threads.

__HPUX10__

Define for all HPUX 10.20 applications.

__SOLARIS__

Solaris directive. Must be defined for Solaris or POSIX threads.

__LINUX__

Linux directive. Must be defined for Linux or POSIX threads.

Conditional Directives Reserved For Future Use In The gxThread Library

:

__MSVC__

Microsoft Visual C++ 4.2 and higher compiler specifics.

__BCC32__

Borland BCC 4.0 and higher compiler specifics.

__MFC__

MFC directive for Windows 95/98/NT MFC applications.

__HPUX__

HPUX directive defined for all versions of HPUX.

__HPUX11__

Define for all HPUX 11.0 and higher applications.

__LINUX_THREADS__

Define for applications using Linux threads.

__SOLARIS_THREADS__

Define for applications using Solaris threads.

Type Definitions

The following type definitions are used in the gxThread library to correctly identify and type cast thread variables between the various platforms. The gxThread types should always be used in place of the native types to ensure that the correct data type is used.

gxThreadID

- Type used to define the platform specific thread ID or HANDLE.

gxStackSizeType

- Define the integer type used to specify a stack size.

gxThreadExitCode

- Defines the integer type used to hold a thread's exit code.

gxThreadKey -

Type used to define the platform specific key type used for thread-specific values

gxThreadAttribute -

Type used to define the platform specific thread attribute structure.

gxThreadObjectID -

Defines the integer type used for a thread's object ID

gxThreadClassID -

Defines the integer type used for a thread's for class ID

Enumerations

The following enumerations are used define integer constants used throughout the gxThread library.

    enum gxThreadState {        // Thread state enumeration
    gxTHREAD_STATE_INVALID = 0, // The current state of this thread is unknown
    gxTHREAD_STATE_CANCELED,    // Thread has been canceled
    gxTHREAD_STATE_EXITED,      // Thread has exited
    gxTHREAD_STATE_NEW,         // Newly created thread
    gxTHREAD_STATE_RUNNING,     // Thread is currently running
    gxTHREAD_STATE_SUSPENDED,   // Thread has been suspended
    gxTHREAD_STATE_WAITING      // Execution is blocked waiting for a signal
    };

    enum gxThreadPriority {        // Thread priority enumeration
    gxTHREAD_PRIORITY_INVALID = 0, // The priority of this thread is invalid
    gxTHREAD_PRIORITY_LOW,         // Move to the bottom of the priority chain
    gxTHREAD_PRIORITY_NORMAL,      // Add to the priority chain (default)
    gxTHREAD_PRIORITY_HIGH         // Move to the top of the priority chain
    };

    enum gxThreadPriorityClass {         // Thread scheduling policies
    gxTHREAD_PRIORITY_CLASS_INVALID = 0, // The priority class is invalid

    // POSIX scheduling policies. NOTE: The WIN32 scheduling policy is
    // determined by the priority class of its process. None of these
    // policies have any effect under WIN32.
    gxTHREAD_PRIORITY_CLASS_OTHER, // Another scheduling policy (default policy)
    gxTHREAD_PRIORITY_CLASS_FIFO,  // First in-first out (FIFO) scheduling policy
    gxTHREAD_PRIORITY_CLASS_RR     // Round robin scheduling policy
    };

    enum gxThreadError {     // Thread error code enumeration
    gxTHREAD_NO_ERROR = 0,   // No errors reported
    gxTHREAD_INVALID_CODE,   // Invalid error code
    gxTHREAD_CANCEL_ERROR,   // Error canceling thread
    gxTHREAD_CLOSE_ERROR,    // Error closing thread
    gxTHREAD_CREATE_ERROR,   // Error creating thread
    gxTHREAD_RUNNING_ERROR,  // Thread is already running
    gxTHREAD_EXECUTE_ERROR,  // Thread cannot be executed
    gxTHREAD_POLICY_ERROR,   // Cannot retrieve thread scheduling policy
    gxTHREAD_PRIORITY_ERROR, // Error setting the thread priority
    gxTHREAD_RESUME_ERROR,   // Error resuming thread
    gxTHREAD_SCHED_ERROR,    // Scheduling error
    gxTHREAD_SCOPE_ERROR,    // Contention scope error
    gxTHREAD_STACK_ERROR,    // Error setting the stack size
    gxTHREAD_STATE_ERROR,    // Could not set the thread state
    gxTHREAD_SUSPEND_ERROR   // Error suspending thread
    };

    enum gxThreadType {     // Thread type enumeration
    gxTHREAD_TYPE_DETACHED, // System reclaims resources when thread terminates
    gxTHREAD_TYPE_JOINABLE  // Thread exit code is available after termination
    };

    enum gxProcessType {   // Process type enumeration
    gxPROCESS_PRIVATE = 0, // Resources are available only to a single process
    gxPROCESS_SHARED =  1  // Resources are available to multiple processes
    };

Derived Class Interface

The gxThread derived class interface consists of three functions:

virtual void *gxThread::ThreadEntryRoutine(gxThread_t *thread) = 0 -

A derived class must override the gxThread::ThreadEntryRoutine() function, which is the thread's entry point of execution. The gxThread_t pointer is available to the derived class to allow the derived class to access thread variables.

virtual void gxThread::ThreadExitRoutine(gxThread_t *thread) -

The gxThread::ThreadExitRoutine() function can be overridden by a derived class to perform any additional operations required before the thread exits. The gxThread_t pointer is available to the derived class to allow the derived class to access thread variables.

virtual void gxThread::ThreadCleanupHandler(gxThread_t *thread) -

The gxThread::ThreadCleanupHandler should be overridden by a derived class if any cleanup operations need to be performed prior to thread cancellation. The gxThread_t pointer is available to the derived class to allow the derived class to access thread variables.

Thread Functions

gxThread::CancelThread
gxThread::CloseThread
gxThread::ConstructThread
gxThread::CreateThread
gxThread::DestroyThread
gxThread::ExitThread
gxThread::JoinThread
gxThread::ResumeThread
gxThread::SetThreadPriority
gxThread::SuspendThread
gxThread::ThreadGetSpecific
gxThread::ThreadKeyCreate
gxThread::ThreadKeyDelete
gxThread::ThreadSetSpecific

int gxThread::CancelThread(gxThread_t *thread)

- Function used to cancel a thread during an operation when the thread is not allocating resources or accessing locked variables. Returns a non-zero value if the thread cannot be canceled. NOTE: The gxThread::ThreadCleanupHandler should be overridden by a derived class if any cleanup operations need to be performed prior to thread cancellation.

int gxThread::CloseThread(gxThread_t *thread)

- Close the thread's handle prior to destruction to indicate that the that storage space for the thread resources can be reclaimed. Returns a non-zero value if the thread cannot be closed.

gxThread_t * gxThread::ConstructThread(gxThreadType t = gxTHREAD_TYPE_JOINABLE, gxStackSizeType ssize = 0)

- First of two overloads used to construct a new thread without executing it. Returns the newly constructed thread container or null if thread cannot be constructed.

gxThread_t * gxThread::ConstructThread(void *parm, gxThreadType t = gxTHREAD_TYPE_JOINABLE, gxStackSizeType ssize = 0)

- Second of two overloads used to construct a new thread without executing it. Returns the newly constructed thread container or null if thread cannot be constructed. This overload allows you to pass a parameter to the thread and optionally set the thread type and stack size.

gxThread_t * gxThread::CreateThread(gxThreadType t = gxTHREAD_TYPE_JOINABLE, gxStackSizeType ssize = 0)

- First of three overloads used to create and execute a new thread. NOTE: Any errors that occur will be recorded in gxThread_t::thread_error member and can be obtained by the application with a call to the gxThread_t::GetThreadError() function. Any errors reported by the thread's entry function can be obtained with a call to the gxThread_t::GetThreadExitCode() function.

gxThread_t * gxThread::CreateThread(void *parm, gxThreadType t = gxTHREAD_TYPE_JOINABLE, gxStackSizeType ssize = 0)

- Second of three overloads used to create and execute a new thread. NOTE: Any errors that occur will be recorded in gxThread_t::thread_error member and can be obtained by the application with a call to the gxThread_t::GetThreadError() function. Any errors reported by the thread's entry function can be obtained with a call to the gxThread_t::GetThreadExitCode() function. This overload allows you to pass a parameter to the thread and optionally set the thread type and stack size.

int gxThread::CreateThread(gxThread_t *thread)

- Third of three overloads used to execute the specified thread, which was constructed by another entity. Returns a non-zero value if any errors occur.

int gxThread::DestroyThread(gxThread_t *thread, int check_state = 1)

- Destroy a thread previously created with a call to the gxThread::CreateThread() function. If the "check_state" variable is true the thread's current state will be evaluated before the thread is destroyed. Returns a non-zero value if the thread cannot be destroyed.

void * gxThread::ExitThread(gxThread_t *thread, int exit_code)

- Exit function used by threads wishing to terminate explicitly in the middle of a task without terminating the whole process. Returns a pointer to the thread's exit code to allow this function to be used as a return value. NOTE: This function should only be called inside the thread entry routine, exit routine or cleanup handler.

int gxThread::JoinThread(gxThread_t *thread)

- This function will force a process to wait until the specified thread has finished execution before allowing the process to continue. Returns a non-zero value if any errors occur or the thread is not joinable.

int gxThread::ResumeThread(gxThread_t *thread)

- Resume a thread that is currently suspended. Returns a non-zero value if any errors occur.

int gxThread::SetThreadPriority(gxThread_t *thread)

- First of three overloads used to set or change the priority and scheduling policy of the a thread in accordance with gxThread_t::thread_priority and thread_class members. Returns a non-zero value if the priority or policy can not be changed. NOTE: Do to cross-platform issues the thread priority is no longer set when the thread is created. This function must be used to change a thread priority after it has been created.

int gxThread::SetThreadPriority(gxThread_t *thread, gxThreadPriority prio)

- Second of three overloads used to set or change the priority of the specified thread. Returns a non-zero value if the priority can not be changed.

int gxThread::SetThreadPriority(gxThread_t *thread, gxThreadPriority prio, gxThreadPriorityClass prio_class)

- Third of three overloads used to set or change the priority and scheduling policy of the specified thread. Returns a non-zero value if the priority or policy can not be changed. NOTE: The WIN32 scheduling policy is determined by the priority class of its process and will not be set here.

int gxThread::SuspendThread(gxThread_t *thread)

- Suspend a thread that is currently running. Returns a non-zero value if any errors occur. NOTE: This function should only be called inside the thread entry routine, exit routine or cleanup handler.

void * gxThread::ThreadGetSpecific(gxThreadKey &key)

- Returns the value currently bound to the specified key for the calling thread. Returns a non-zero value if an error occurs.

int gxThread::ThreadKeyCreate(gxThreadKey &key)

- Creates a thread-specific data key. Returns a non-zero value if any errors occur.

int gxThread::ThreadKeyDelete(gxThreadKey &key)

- Releases a thread local storage key. NOTE: It is the responsibility of the application to free any allocated dynamic storage associated with this key prior to calling this function. Returns a non-zero value if any errors occur.

int gxThread::ThreadSetSpecific(gxThreadKey &key, const void *value)

- Stores a value in the calling thread's thread local storage slot for the specified thread. Returns a non-zero value if any errors occur.

Pool Functions

gxThread::ConstructThread
gxThread::ConstructThreadPool
gxThread::CreateThread
gxThread::CreateThreadPool
gxThread::DestoryThreadPool
gxThread::JoinThread
gxThread::RebuildThreadPool

gxThread_t * gxThread::ConstructThread(thrPool *thread_pool, gxThreadPriority prio = gxTHREAD_PRIORITY_NORMAL, gxThreadType t = gxTHREAD_TYPE_JOINABLE, gxStackSizeType ssize = 0)

- First of two overloads used to construct a new thread and throw it in the specified thread pool without executing it. Returns the newly constructed thread or null if thread cannot be constructed. NOTE: The thread priority will determine its priority in the thread queue.

gxThread_t * gxThread::ConstructThread(thrPool *thread_pool, void *parm, gxThreadPriority prio = gxTHREAD_PRIORITY_NORMAL, gxThreadType t = gxTHREAD_TYPE_JOINABLE, gxStackSizeType ssize = 0)

- Second of two overloads used to construct a new thread and throw it in the specified thread pool without executing it. Returns the newly constructed thread or null if thread cannot be constructed. NOTE: The thread priority will determine its priority in the thread queue. This overload allows you to pass a parameter to the thread when it is constructed.

thrPool * gxThread::ConstructThreadPool(unsigned pool_size) - Construct a new thread pool with the specified number of nodes. NOTE: None of threads in the pool will be executed. Returns a pointer to the newly constructed thread pool or a null value if the pool could not be created.

gxThread_t * gxThread::CreateThread(thrPool *thread_pool, gxThreadPriority prio = gxTHREAD_PRIORITY_NORMAL, gxThreadType t = gxTHREAD_TYPE_JOINABLE, gxStackSizeType ssize = 0)

- First of two overloads used to create a new thread and throw it in the specified thread pool after executing it. Returns the newly constructed thread or null if thread cannot be constructed. NOTE: The thread priority will determine its priority in the thread queue.

gxThread_t * gxThread::CreateThread(thrPool *thread_pool, void *parm, gxThreadPriority prio = gxTHREAD_PRIORITY_NORMAL, gxThreadType t = gxTHREAD_TYPE_JOINABLE, gxStackSizeType ssize = 0)

- Second of two overloads used to create a new thread and throw it in the specified thread pool after executing it. Returns the newly constructed thread or null if thread cannot be constructed. NOTE: The thread priority will determine its priority in the thread queue. This overload allows you to pass a parameter to the thread before it is executed.

thrPool *gxThread::CreateThreadPool(unsigned pool_size, void *parm, gxThreadPriority prio, gxThreadType t, gxStackSizeType ssize)

- Create a new thread pool and execute each thread in the pool as it is created. Returns a pointer to the newly created thread pool or a null value if the pool could not be created.

int gxThread::DestoryThreadPool(thrPool *thread_pool, int check_state = 1)

- Destroy a previously created thread pool. If the "check_state" variable is true the current state of each thread will be checked before it is destroyed. If a thread cannot be canceled and the "check_state" variable is true, this function will return a non-zero value.

int gxThread::JoinThread(thrPool *thread_pool)

- Make the process wait until all the threads in the specified pool have finished executing. Returns a non-zero value if the threads cannot be joined.

void gxThread::RebuildThreadPool(thrPool *thread_pool)

- Remove all the threads in the pool that have exited or have been canceled.

Timer Functions

void gxThread::mSleep(int milliseconds)

- Suspends the execution of the current thread for a specified number of milliseconds.

void gxThread::sSleep(int seconds)

- Suspends the execution of the current thread for a specified number of seconds.

End Of Document