Java provides the
Thread class that enables developers to easily create multiple threads in Java applications. Pthreads is commonly used for multithreaded programming in C and C++, but this API is procedural and somewhat less convenient to use than Java’s object oriented thread interface.
However, it is possible to mimic Java thread behaviors by wrapping Pthreads calls in a C++ class that will let you create threads Java style.
Java Threads Overview
With Java all you have to do to create a thread is subclass
Thread overriding the
run() method with your own method that will do what you want you thread to do. Here’s a quick example from the Oracle Java docs page:
This code would then create and run a Java thread:
Thread class also provides methods to start the thread at time of the caller’s choosing, wait for the thread to finish and detach the thread so that it does not require another thread to wait for it to finish.
Thread Class Interface
Let’s start with the C++
Thread class declaration which will be contained in a header file thread.h. We need to include pthread.h for the Pthreads API. Public methods include: constructor, destructor,
detach() and get thread ID (
virtual run method to
0 forces this class to be abstract and requires that
run() to be overriden in any subclass of
Thread. The destructor is also declared virtual to make sure that a Thread subclass object destructor is called when the object is deleted thought a base
Thread class pointer.
The class features three private member variables.
m_tid– contains the thread ID
m_running– flag that is
0when the thread is not running or
1when it is
m_detached– flag that is
0when the thread is not detached or
1when it is. I’ll have more to say about thread detatched state later in the article.
Thread Class Definition
Thread class definition is included in the thread.cpp file. The constuctor method is very simple. It just initializes the member variables to
When destroying a Thread object we want to check to see if the thread is still running and stop it if it is. The call to
pthread_cancel() will ensure the thread is shutdown at some point in the future. If we did not do this the thread woud continue to run, possibly indefinitely, after the Thread class shell around it was destroyed. If the thread is not detached then we want to detach it as well.
start() method calls
pthread_create() to create the thread. The function accepts four arguments:
- Pointer to a
pthread_tvariable that contains the thread ID. Set this to the address of
- Pointer to a an attributes object. Set this to
NULLto set up default attributes.
- Pointer to a function that is called when the thread starts to take the thread action. The function must accept a void pointer to an object and return a void pointer to an object. Set this to the address of the
runThread()function, the prototype for which is shown below.
- Pointer to a data object that will be passed to the thread action function. Set to the
Threadclass this pointer. We’ll use this pointer to call the
Thread::run()method in the
Pthread functions return 0 when they are successful and an integer >
0 when they fail. When the call to
pthread_create() returns we check the return code. If it is
0 that means the thread was successful so set the
m_running flag to 1. The thread
m_tid member variable is set to the thread ID which is used subsequent Pthread function calls.
In the call to
pthread_create() the last argument is a void pointer to a data structure which will be passed to the
runThread() function when it is called. Since the input argument to the
runThread() is the Thread class this pointer, we can cast it to a
Thread pointer then use it to call the
Thread::run() method. Due to polymorphism, the
run() method will be called to carry out the thread’s action.
By default Pthreads are joinable. meaning you can wait for them to complete with a call to
Thread class join method checks to see if the thread is running, then calls this function to wait for the thread to complete. If the call is successful the thread is marked as detached since
pthread_join() automatically detatches a thread.
This is a utility method that detaches a thread when the caller doesn’t want to wait for the thread to complete. If the thread is running and not detached,
pthread_detach() is called and the thread is flagged as detached if the call is successful.
Get Thread ID
This is another utility method that returns the thread ID for display or logging purposes.
Create Thread Subclass
The test application is defined in the main.cpp file. First we create a
Thread subclass called
MyThread that supplies a run method which simply prints a message to
stdout five times then quits. Each time through the loop a delay of 2 seconds is added so it is easier to observe what it displayed on stdout. Each message will display the Pthread ID which is cast as a
long unsigned int. For this simple thread class we don’t need set up any internal data so we don’t have to supply a constructor or destructor. The base class constructor and destructor are sufficient.
Next we define a
main() function that will create two
MyThread objects, start them and then wait for each to finish.
Build and Run
You can get the source code for the project from Github – https://github.com/vichargrave/threads. To build it just cd into the project directory and type make.
Running the app will produce the following output: