HPC++ Thread Class

HPC++ uses a model of threads that is based on a Thread class which is, by design, similar to the Java thread system. More specifically, there are two basic classes that are used to instantiate a thread and get it to do something. Basic Thread objects encapsulate a thread and provide a private data space. Objects of class HPCxx_Runnable provide a convenient way for a set of threads to execute the member functions of a shared object.

The interface for Thread is given by

class HPCxx_Thread{
   public:
       HPCxx_Thread(const char *name = NULL);
       HPCxx_Thread(HPCxx_Runnable *runnable, 
                    const char *name = NULL);
       virtual ~HPCxx_Thread();
       HPCxx_Thread& operator=(const HPCxx_Thread& thread);
       virtual void run();
       static void stop(void *status);
       static void yield();
       void resume();
       int isAlive();
       static HPCxx_Thread *currentThread();
       void join(long milliseconds = 0, 
                 long nanoseconds = 0);
       void setName(const char *name);
       const char *getName();
       int getPriority();
       int setPriority(int priority);
       static void sleep(long milliseconds, 
                         long nanoseconds = 0);
       void suspend();
       void start();
 };
The interface for HPCxx_Runnable is given by
class HPCxx_Runnable{
  public:
   virtual void run() = 0;
};

There are two ways to create a thread and give it work to do. The first is to create a subclass of HPCxx_Runnable which provides an instance of the run() method. For example, to make a class that prints a message we can write

 class MyRunnable: public HPCxx_Runnable{
      char *x;
    public:
      MyRunnable(char *c): x(c){}
      void run(){
          printf(x); 
          }
};
The program below will create an instance of two threads that each run the run() method for a single instance of a runnable object.
      MyRunnable r("hello world");
      Thread *t1 = new Thread(&r);
      Thread *t2 = new Thread(&r);
      t1->start();  // launch the thread but don't block
      t2->start();
This program prints
hello worldhello world

It is not required that a thread have an object of class HPCxx_Runnable to execute. One may subclass Thread to provide a private data and name space for a thread and overload the run() function there as shown below.

class MyThread: public HPCxx_Thread{
      char *x;
   public:
      MyThread(char *y): x(y), HPCxx_Thread(){}
      void run(){
           printf(x);
           }
};
int main(int argv, char *argc){
      HPCxx_Group *g;
      hpcxx_init(&argv, &argc, g);

      MyThread *t1 = new MyThread("hello");
      t1->start();
       
      return hpcxx_exit(g);  
}

The decision for when to subclass Thread or HPCxx_Runnable depends upon the application. As we shall seen in the section on implementing HPC++ parallel loops, there are times when both approaches are used together.

The initialization function hpcxx_init() strips all command line flags of the form -hpcxx_ from the argv array so that application flags are passed to the program in normal order. This call also initializes the object g of type HPCxx_Group which is used for synchronization purposes and is described in greater detail in the Synchronization section. The termination function hpcxx_exit() is a clean up and termination routine.

It should be noted that in this small example, it is possible for the main program to terminate prior to the completion of the two threads. This would signal an error condition. We will discuss the ways to prevent this from happening in the section on synchronization.


hpc++@extreme.indiana.edu

Last modified: Tue Apr 20 22:06:08 EST 1999