Qubit
Qubit

Reputation: 61

How to pass parameters and function to pthread_create

Okay so i'm looking at the documentation for pthread_create and I just don't understand at all how to do what I want to do.

I want to call pthread_create which will obv pass in a struct of pthread_t. But the function I pass to it takes in a pointer to a of MyNode*. How would I pass the function as a parameter and pass it "this" as a parameter to that function.

//MyNode field and method in class file
pthread_t myTrd;  

static void compute(MyNode* node);

////////////////////////////////////////////////////////////
//Actual code in header file below
static void MyNode::compute(*MyNode node){ //L61
  //code
}

void MyNode::run(){ //run function in header file
    pthread_create(&(this->thread),NULL,MyNode::compute, this);
}

outcome:

myNode.cpp:61: error: 'static' may not be used when defining (as opposed to declaring) a static data member
myNode.cpp:61: error: 'int MyProjectGraph::MyNode::compute' is not a static member of 'class MyProjectGraph::MyNode'
myNode.cpp:61: error: expected primary-expression before 'node'
myNode.cpp:61: error: expected ',' or ';' before '{' token
myNode.cpp:134: error: expected `}' at end of input

Upvotes: 1

Views: 3035

Answers (2)

user1580309
user1580309

Reputation: 11

Having a thread per object isn't really a good way to go. I presume that since you are calling your object a node, you have a bunch of them and want to do something to them on a thread. I typically do the following, which is a classic idiom:

class Worker
{
    struct ThreadStr
    {
        Worker * worker;
        // put parameters here
        MyNode * node;
};


public:

    static void *StaticHandler(void *pvoid)
    {
        ThreadStr * data = (ThreadStr*)pvoid;
        data->worker->Compute(data->node);
        delete data;
        return NULL;
    }

    void Compute(MyNode *node)
    {
        // whatever you want to compute on a node.
    }

    // start a thread to execute Worker::Compute(MyNode*)
    void Run(MyNode *node)
    {
        ThreadStr * data = new ThreadStr();
        data->worker = this;
        data->node = node;

        pthread_t threadId;
        pthread_create(&threadId, NULL, Worker::StaticHandler, data);

    }

};

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 753525

The function passed to pthread_create() should match the prototype:

void *function(void *arg);

If your function does not match that, you have to use brute force and ignorance (and a cast) to make the function pointer acceptable — and then hope that the alternative interface doesn't break anything.

It is far better to make your function match the specification:

void *function(void *arg)
{
    MyNode *mnp = (MyNode *)arg;
    …
    return 0;
}

The return can return some more meaningful value if you have one available, but returning a null (you could probably write nullptr given that you're mainly using C++).

Note that pthread_create() is usually a C function itself and expects C function semantics in the function pointer it is passed.

Upvotes: 2

Related Questions