C++ : How to pass class member function to pthread_create() ?

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.

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

 

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top