POSIX Library provides a function pthread_create() to create threads i.e.
#include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
It accepts a function pointer as startup routine. This function accepts void * as argument and returns void *. In previous article we discussed how to use this API with global functions to start thread i.e.
POSIX : How to create a thread using pthread_create()
In this article we will discuss how to pass class member functions to pthread_create as startup routine for the thread.
Suppose we have a class Task and it has two member functions, one static and another non static i.e.
class Task { public: void * execute(); static void * threadFunc(void *); };
Now will see how to create a pthread using both static and non static function of class Task.
Frequently Asked:
- POSIX : How to create a thread | pthread_create() example & Tutorial
- C++ : How to pass class member function to pthread_create() ?
Passing non static member function to pthread_create()
class Task and it has a non static function execute() i.e.
void * Task::execute() { std::cout << "Task :: execute from Thread ID : " << pthread_self() << std::endl; return NULL; }
Now we want to pass this member function Task::execute() as thread function in pthread_create(). As pthread_create() accepts a function pointer as an argument of following type i.e.
void * (*)( void *)
So, typecast Task::execute with type. Also, as compiler pass the pointer of class (this pointer) as first argument in every member function. So, pass pointer to the object of class Task as an argument i.e.
typedef void * (*THREADFUNCPTR)(void *); // Pointer to object of class Task Task * taskPtr = new Task(); //Thread ID pthread_t threadId; // Create thread using memeber function as startup routine pthread_create(&threadId, NULL, (THREADFUNCPTR) &Task::execute,taskPtr);
Passing Static member function to pthread_create()
Suppose we have a static function in class Task i.e.
void * Task::threadFunc(void *) { std::cout << "Task :: threadFunc from Thread ID : " << pthread_self() << std::endl; return NULL; }
To pass a static member function in pthread_create(), type case it as above i.e. with,
void * (*)( void *)
But as static functions are not associated with any object and therefore compiler doesn’t pass this pointer to it. So, we do’t need to pass any pointer as argument. Just pass NULL i.e.
typedef void * (*THREADFUNCPTR)(void *); // Create pthread using static function as startup routine pthread_create(&threadId, NULL, (THREADFUNCPTR) &Task::threadFunc, NULL);
Complete example is as follows,
#include <iostream> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <pthread.h> #include <unistd.h> class Task { public: void * execute(); static void * threadFunc(void *); }; void * Task::execute() { std::cout << "Task :: execute from Thread ID : " << pthread_self() << std::endl; return NULL; } void * Task::threadFunc(void *) { std::cout << "Task :: threadFunc from Thread ID : " << pthread_self() << std::endl; return NULL; } typedef void * (*THREADFUNCPTR)(void *); int main() { /***** Create a New Thread From non static member function******/ Task * taskPtr = new Task(); // Thread id pthread_t threadId; // Create a thread and pass class member function Task::execute as argument i.e. thread function // type cast it with a function pointer of type = void * (*)(void *). // As member function takes this pointer of same class as first argument i.e. this pointer // So, pass the pointer to the object of class task as argument to thread function int err = pthread_create(&threadId, NULL, (THREADFUNCPTR) &Task::execute,taskPtr); // Check if thread is created successfully if (err) { std::cout << "Thread creation failed : " << strerror(err); return err; } // Do some stuff in Main Thread std::cout << "Waiting for thread " << threadId << " to exit" << std::endl; // Wait for thread to exit, pass thread id as first argument err = pthread_join(threadId, NULL); if (err) return err; delete taskPtr; // Create a thread and pass class static member function Task::threadFunc as argument i.e. thread function // type cast it with a function pointer of type = void * (*)(void *). // As in static function compiler dont pass the this pointer as first argument, hence no need // to pass the pointer to the object of class Task. err = pthread_create(&threadId, NULL, (THREADFUNCPTR) &Task::threadFunc, NULL); // Check if thread is created successfully if (err) { std::cout << "Thread creation failed : " << strerror(err); return err; } // Do some stuff in Main Thread std::cout << "Waiting for thread " << threadId << " to exit" << std::endl; // Wait for thread to exit, pass thread id as first argument err = pthread_join(threadId, NULL); std::cout << "Exiting Main" << std::endl; return 0; }
Output:
Waiting for thread 139853389993728 to exit Task :: execute from Thread ID : 139853389993728 Waiting for thread 139853389993728 to exit Task :: threadFunc from Thread ID : 139853389993728 Exiting Main
To compile the above code use following command,
g++ example.cpp -lpthread