1

I'm trying to run a function named extensionStep from a class named SVAnchor in multi threads. i use this code:

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

to call the function and here is the definition of extensionStep :

void* SVAnchor::extensionStep( void *threadarg)

and i got the following error:

error: cannot convert 'SVAnchor::extensionStep' from type 'void* (SVAnchor::)(void*)' to type 'void* (*)(void*)'
           rc = pthread_create(&threads[i], NULL, extensionStep, &td[i]);
                                                                       ^

that shows the problem is converting from type 'void* (SVAnchor::)(void*)' to type 'void* ()(void)'

How to solve this problem?

Thanks all

ameerosein
  • 523
  • 3
  • 16
  • 2
    You should consider std::thread (if c++11) –  Sep 23 '16 at 08:35
  • @DieterLücking you mean pthreads doesn't support this thing? it's really expensive for me to go to std::thread – ameerosein Sep 23 '16 at 08:42
  • @ameerosein Try doing rc = pthread_create(&threads[i], NULL, &(SVAnchor::extensionStep), &td[i]); – nishantsingh Sep 23 '16 at 08:45
  • @user3286661 didn't help :( – ameerosein Sep 23 '16 at 08:47
  • std::thread uses pthread under POSIX & Linux systems. You are just using function calls wrong – gj13 Sep 23 '16 at 08:49
  • @ameerosein You seem to be asking a number of questions on pthreads, and each and every time, people suggest that you should use c++11 threads. Your questions require some ingenuity using pthreads, but are really easy using c++11 threads. Maybe you should take the time to read a tutorial of c++11. – Ami Tavory Sep 23 '16 at 09:28
  • @AmiTavory Hum you're right i have to, do you know a good tutorial for that ? thanks – ameerosein Sep 23 '16 at 10:06
  • @ameerosein They're plenty - [here's one](https://solarianprogrammer.com/2011/12/16/cpp-11-thread-tutorial/). – Ami Tavory Sep 23 '16 at 10:11

2 Answers2

1

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.

nishantsingh
  • 4,537
  • 5
  • 25
  • 51
  • @PaulRooney i'm using the function inside another class member function, so there's no class_variable_name ! what should i do ? – ameerosein Sep 23 '16 at 09:30
  • If its inside SVAnchor then it will be 'this' – PaulHK Sep 23 '16 at 09:33
  • @ameerosein use `arg.ptr = this;` in that case. – nishantsingh Sep 23 '16 at 09:39
  • @paulRooney is `static void *extensionStepWrapper(void *arg)` a class member function? and then i should define it this way: `static void * SVAnchor::extensionStepWrapper(void *arg)` ? but it results in error.. – ameerosein Sep 23 '16 at 09:49
  • @ameerosein You don't write static keyword while defining the function. You write it only in declaration. Read [this](http://stackoverflow.com/questions/5373107/how-to-implement-static-class-member-functions-in-cpp-file). – nishantsingh Sep 23 '16 at 09:52
  • and the first option didn't work for me :( lots of errors like: invalid use of other members in static member function... – ameerosein Sep 23 '16 at 09:53
  • @ameerosein Read my previous comment regarding how to implement static functions. – nishantsingh Sep 23 '16 at 09:55
  • corrected but lots of errors like: invalid use of other members in static member function.. – ameerosein Sep 23 '16 at 09:57
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/124021/discussion-between-user3286661-and-ameerosein). – nishantsingh Sep 23 '16 at 09:59
1

This is a common mapping of a class member function to a C-callback:

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

class Task
{
    public:
    Task() : thread_id(0) {}

    bool start() {
        // Passing this as user data to the C-callback.
        return pthread_create(&thread_id, 0, invoke, this) == 0;
    }

    void stop() {
        void* no_result;
        pthread_join(thread_id, &no_result);
    }

    private:
    Task(const Task&); // no copy (C++11 delete)
    Task& operator = (const Task&); // no copy (C++11 delete)

    void process() {
        std::cout << "Hello\n";
    }

    // The C-callback has to be static.
    static void* invoke(void* self) {
        // Note: The invocation takes place in start (passing this) 
        static_cast<Task*>(self)->process();
        // No result passed to join.
        return 0;
    }

    pthread_t thread_id;
};

int main() {
    Task task;
    task.start();
    task.stop();
}

This is a C++11 version:

#include <iostream>
#include <thread>

class Task
{
    public:
    void operator () () {
        std::cout << "Hello\n";
    }
};

int main() {
    Task task;
    std::thread thread(task);
    thread.join();
}