Here is an example that shows how to successfully create a program that abstracts a thread into a C++ class.
You could easily extend this example to provide a mechanism by which the thread creation and manipulation itself is also encapsulated into the class.
When sharing objects between threads, always be aware of which thread is manipulating the object, which thread is responsible for freeing the object, and what thread safety issues are created by sharing objects between threads.
/* This C++ example must be compiled with Visual Age C++ for OS/400 */
#define _MULTI_THREADED
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <pthread.h>
class ThreadClass {
public:
ThreadClass(char *s) {
data1 = 42; data2 = strlen(s);
strncpy(str, s, sizeof(str)-1);
str[49]=0;
}
void *run(void);
private:
int data1;
int data2;
char str[50];
};
extern "C" void *ThreadStartup(void *);
int main(int argc, char **argv)
{
ThreadClass *t=NULL;
pthread_t thread;
int rc;
// Use printf instead of cout.
// At the time this test was written, the C++ standard class library
// was not thread safe.
printf("Entered test %s\n", argv[0]);
printf("Create a ThreadClass object\n");
t = new ThreadClass("Testing C++ object/thread creation\n");
printf("Start a real thread to process the ThreadClass object\n");
// #define COMPILE_ERROR
#ifdef COMPILE_ERROR
// This is an ERROR. You cannot create a thread by using a pointer
// to a member function. Thread creation requires a C linkage function.
// If you remove the comments from the line `#define COMPILE_ERROR'
// the compiler will give a message similar to this:
// "ATESTCPP0.C", line 46.53: 1540-055: (S) "void*(ThreadClass::*)()"
// cannot be converted to "extern "C" void*(*)(void*)".
rc = pthread_create(&thread, NULL, ThreadClass::run, NULL);
#else
// Instead, this is the correct way to start a thread on a C++ object
rc = pthread_create(&thread, NULL, ThreadStartup, t);
#endif
if (rc) {
printf("Failed to create a thread\n");
exit(EXIT_FAILURE);
}
printf("Waiting for thread to complete\n");
rc = pthread_join(thread, NULL);
if (rc) {
printf("Failed to join to the thread, rc=%d\n");
exit(EXIT_FAILURE);
}
printf("Testcase complete\n");
exit(EXIT_SUCCESS);
}
// This function is a helper function. It has normal C linkage, and is
// as the base for newly created ThreadClass objects. It runs the
// run method on the ThreadClass object passed to it (as a void *).
// After the ThreadClass method completes normally (i.e returns),
// we delete the object.
void *ThreadStartup(void *_tgtObject) {
ThreadClass *tgtObject = (ThreadClass *)_tgtObject;
printf("Running thread object in a new thread\n");
void *threadResult = tgtObject->run();
printf("Deleting object\n");
delete tgtObject;
return threadResult;
}
void *ThreadClass::run(void)
{
printf("Entered the thread for object %.8x %.8x %.8x %.8x\n", this);
printf("Object identity: %d, %d: %s\n", data1, data2, str);
return NULL;
}
Output
Entered test QP0WTEST/ACPPOBJ Create a ThreadClass object Start a real thread to process the ThreadClass object Waiting for thread to complete Running thread object in a new thread Entered the thread for object 80000000 00000000 d017dad2 57001f60 Object identity: 42, 35: Testing C++ object/thread creation Deleting object Testcase complete