Pthread Function from a Class

pthread function from a class

You can't do it the way you've written it because C++ class member functions have a hidden this parameter passed in. pthread_create() has no idea what value of this to use, so if you try to get around the compiler by casting the method to a function pointer of the appropriate type, you'll get a segmetnation fault. You have to use a static class method (which has no this parameter), or a plain ordinary function to bootstrap the class:

class C
{
public:
void *hello(void)
{
std::cout << "Hello, world!" << std::endl;
return 0;
}

static void *hello_helper(void *context)
{
return ((C *)context)->hello();
}
};
...
C c;
pthread_t t;
pthread_create(&t, NULL, &C::hello_helper, &c);

Calling a class member function from a thread using pthread_create

You can do this via a function that dispatches the work accordingly:

#include <iostream>
#include <pthread.h>

struct Base {
virtual void work() {
std::cout << "Base::work()\n";
}

virtual ~Base() {}
};

struct Derived : public Base {
void work() override {
std::cout << "Derived::work()\n";
}
};

void* thread_adapter(void* obj) {
Base* p = static_cast<Base*>(obj);
p->work();
return nullptr;
}

int main() {
Derived d;
pthread_t thread;
pthread_create(&thread, nullptr, thread_adapter, &d);
pthread_join(thread, nullptr);
}

Live example

pthread_create accepts a pointer to arbitrary data for the thread function. Pass the address of your object, and use a forwarding function such as the thread_adapter defined above. Inside the adapter function, you can static_cast the argument back to a Base* inside your thread function and invoke the member function as desired.

However, you may want to look into the std::thread library, which supports such operations in a more natural way:

#include <iostream>
#include <thread>

struct Base {
virtual void work() {
std::cout << "Base::work()\n";
}

virtual ~Base() {}
};

struct Derived : public Base {
void work() override {
std::cout << "Derived::work()\n";
}
};

int main() {
Derived d;
std::thread t(&Base::work, d);
t.join();
}

Live example

pass the class method as pthread start function [duplicate]

The 'usual' approach is, to pack the object and all function arguments into a struct, allocate this struct on the heap, pass an instance of this struct to a function with C binding and let that function call the objects member function:

struct wrap {
char * msg;
Foo ins;

wrap( char* m, const Foo& f ) : msg(m), ins(f) {}
};

extern "C" void* call_func( void *f )
{
std::auto_ptr< wrap > w( static_cast< wrap* >( f ) );
w->ins.func(w->msg);

return 0;
}

int main() {
wrap* w = new wrap( "Hi dude", Foo() );
pthread_t pt;

pthread_create( &pt, NULL, call_func, w );
}

How to start pthread inside class constructor on member function of same class?

pthreads uses a C-based API and so it can only use free-standing functions for thread procedures, not non-static class methods. A non-static class method has a hidden this parameter that pthreads doesn't know about.

However, you can declare threadLoop as static instead (to remove the this parameter), and then pass the class's this pointer to threadLoop in its user-defined argument.

Also, you need to resize() your workers container, not reserve() it. reserve() preallocates the container's internal memory, but it does not add new elements (only the capacity() changes, not the size()). Using operator[] to access elements that have not actually been added to the container is undefined behavior.

Try this instead:

class ThreadPool
{
private:
std::vector<pthread_t> workers;
static void* threadLoop (void *arg);
public:
ThreadPool(int num_workers);
...
};

ThreadPool::ThreadPool(int num_workers)
{
workers.resize(num_workers);
for (int i = 0; i < num_workers; i++) {
pthread_create(&workers[i], NULL, threadLoop, this);
}
}

void* ThreadPool:threadLoop (void *arg)
{
ThreadPool *pThis = (ThreadPool*) arg;
// use pThis as needed...
}

Technically speaking, using a non-static class method as a free-standing function is also undefined behavior, but it works fine in most compilers, and there are plenty of libraries that are designed around that functionality. If in doubt, you can always define an actual free-standing function, and make it a friend of your class if it needs to access non-public members.

Pthread_create call function in class [duplicate]

I suggest to you use stl container instead of C arrays.

The Customer::run is static function so you not need pass this function like this:

status = pthread_create (..., Customers[index].run, ...);

For passing static function to pthread you need pass pointer to static function:

status = pthread_create(..., &Customers::run, ...);

Ok we pass function but also I guess you wish to pass concrete Customer object to thread

status = pthread_create(..., &Customers::run, (void *)Customers[index]);

End-version of the code will look like

void *Customer::run(void *arg)
{
Customer *this_ = (Customer *)arg;
// Do something
}

std::list<pthread_t> pthreads(50);
std::list<Customer *> Customers(50);

for (size_t i = 0; i < pthreads.size(); ++i)
{
Customers[i] = new Customer();
status = pthread_create(&pthreads[i], &Customer::run, (void *)Customers[i]);
...
}

for (size_t i = 0; i < pthreads.size(); ++i)
{
pthread_join(pthreads[i]); // block until thread end
delete Customers[i]; // free mem
}

C++ pthread member function [duplicate]

Try making _threaded_run static. In the header:

private:
static void* _threaded_run(void*);

And in the implementation:

void* gtk_functor::_threaded_run(void* win) {
Gtk::Window* w = static_cast<Gtk::Window*>(win);
Gtk::Main::run(*w);
delete w;
}

Then when creating the thread:

pthread_create(&t_num, NULL, >k_functor::_threaded_run, static_cast<void*>(&win));

Pthread for C++ class functions which uses refrence to class object

wrapper1Fun expects to be passed a pointer to a Wrapper, and wrapper2Fun expects to be passed a pointer to a Wraper2. But you're actually passing a pointer to a ThreadWrapper to each, which is a completely different type, so it goes wrong.

The use of void * and casts prevents the compiler from pointing out your type error. I would suggest using a type safe C++ threading library rather than raw pthread. Boost has one, as does the standard library from C++11.

Also your use of auto_ptr is questionable at best. It's deprecated, easy to get wrong, and a poor way of expressing ownership - prefer unique_ptr or shared_ptr.

Here you construct two auto_ptr values owning the same pointer, so it will be freed twice, which is undefined behaviour.

In any case there's no obvious reason to put any of these objects on the heap. If you do, you need to decide where the ownership of the memory resides.

pthread member function of a class with arguments

I think a better solution for using things such as pthread(which take c callbacks) is to create a wrapper function so that you can use much easier to manipulate boost::functions instead. This is similar to Using boost::bind() across C code, will it work?.

Then you could solve your problem simply with boost::bind

class myClass
{
void atom(myStruct *data); // void return type to keep it similar to other code
// You could change it to a void* return type, but then you would need to change the boost::function declarations
};

boost::function<void(void)> function = boost::bind(&myClass::atom,&myClassInstance,&myStructInstance); //bind your function
boost::function<void(void)>* functionCopy = new boost::function<void(void)> (function); //create a copy on the heap

pthread_t id;
pthread_create(&id,NULL,&functionWrapper,functionCopy);

The wrapper function would look like this.

void functionWrapper(void* data)
{

boost::function<void(void)> *func = (boost::function<void(void)>* ) (data);
(*func)();
delete(func);
}

While this method may be more work than manually passing in data, it is much more extendable, making it easy to bind anything and pass it to start your thread.

EDIT

One last note: myClassInstance and myStructInstance should be on the heap. If they are on the stack they could get deleted before your thread starts.

How to multithreading a class member function with pthreads?

This should do the job: (After making the function extensionStep static)

rc = pthread_create(&threads[i], NULL, &(SVAnchor::extensionStep), &td[i]);

Or you can create a wrapper function like this:

struct Argument {
SVAnchor* ptr;
int* tid;
}

static void *extensionStepWrapper(void *arg)
{
return (((Argument*)arg)->ptr)->extensionStep(((Argument*)arg)->tid);
}

And use the wrapper:

Argument arg;
arg.ptr = &(class_variable_name); // Use appropriate name (whatever you variable name is for the object of the class SVAnchor)
arg.tid = &(td[i]);

rc = pthread_create(&threads[i], NULL, &(SVAnchor::extensionStepWrapper), &arg);

Note that if you're calling this from inside another member function, you may do this instead:

arg.ptr = this; 

You can also create a method in the class to start the thread:

bool StartThread(int* tid){
return (pthread_create(&_thread, NULL, extensionStep, tid) == 0);
}

You might also need to pass the thread as argument of StartThread() function.



Related Topics



Leave a reply



Submit