smurf turf
smurf turf

Reputation: 3

C pthread with struct

So we are struggling with a challenge, we need to parallelize c++ code to make sure it uses multiple cores instead of just one. We used openmp for this and it runs a lot better now. But for another part we need to use pthread. Since we are very new to C++ (actually it's the first time we work with it), we have some trouble to get the threads working.

Here is a minimalistic version of the original code:

int main(int argc, char **argv) {
    ...code ...
    //These 2 functions should be running in parallel
    work_calculation(flights, parameter, alliances);
    play_calculation(flights, parameter, alliances);
    ...code...
}

void work_calculation(vector<Flight>& flights, Parameters& parameters, vector<vector<string> >& alliances)
{
    ... code ...
    do_calculation(flights, parameters, alliances);
    ... code ...
}

void do_calculation(vector<Flight>& flights, Parameters& parameters, 
vector<vector<string> >& alliances)
{
    ...code...
}

In order to use pthread with a function which has multiple arguments, we found that we need to use a struct. So we came up with this:

int main(int argc, char **argv) {
    ...code ...
    s_param parathread;
parathread.flights = flights;
parathread.parameters = parameters;
parathread.alliances = alliances;
pthread_t play;
pthread_t work;
pthread_create(&play, NULL, work_calculation ,&parathread);
pthread_create(&work, NULL, play_calculation, &parathread);
pthread_join(play, NULL);
pthread_join(work, NULL);
    ...code...
}

typedef struct 
{
    vector<Flight> flights;
    Parameters parameters;
    vector<vector<string> > alliances;
} s_param;

void* work_calculation(void* args)
    {
        ... code ...
        struct s_param *paraThread = (struct s_param*)args;
        do_calculation(paraThread->flights, paraThread->parameters, paraThread->alliances);
        ... code ...
        pthread_exit(NULL);
    }

void do_calculation(vector<Flight>& flights, Parameters& parameters, 
vector<vector<string> >& alliances)
{
    ...code... (same as original)
}

If we do it like this, we get the following errors:

error: pointer to incomplete class type is not allowed -> everywhere i do paraThread

We also tried without structs in struct s_pram *paraThread = (struct s_param*)args => (so like this: s_param *paraThread = args; , but then we get these errors while compiling:

identifier s_param is undefined and identifier paraThread is undefined

What are we doing wrong? I hope someone can help us to locate the problem.

Upvotes: 0

Views: 490

Answers (5)

Eugene Roeder
Eugene Roeder

Reputation: 219

If you are new to threading I would start with a higher level runtime library for parallization. Low level threading libraries like pthread expose the control of parallelism at its lowest level. There represent the assembly languages of parallelism. As such, they offer maxiumu flexibility, but at a high cost in terms of programmer effort, debugging time, and maintenance costs.

To open source C++ runtimes are cilk Plus and TBB. They have an open source website to download bits from.

www.threadingbuildingblocks.org

www.cilkplus.org

Upvotes: 0

paxdiablo
paxdiablo

Reputation: 882376

The snippet:

typedef struct 
{
    vector<Flight> flights;
    Parameters parameters;
    vector<vector<string> > alliances;
} s_param;

creates a type s_param, not struct s_param. Mike Seymour has the correct answer (incorrect ordering of use and definition) but you'll still need to use either struct or the typedef. I prefer the typedefs myself but others have other ideas.

You'll can use either:

typedef struct {
    vector<Flight> flights;
    Parameters parameters;
    vector<vector<string> > alliances;
} s_param;
:
s_param *something;

or:

struct s_param {
    vector<Flight> flights;
    Parameters parameters;
    vector<vector<string> > alliances;
};
:
struct s_param *something; // I think struct is optional but I still prefer it.

Upvotes: 0

user1284631
user1284631

Reputation: 4616

Move the definition of typedef struct {} s_param at the beginning of the file.

Upvotes: 0

Mike Seymour
Mike Seymour

Reputation: 254701

The struct needs to be defined before you instantiate it in main; you are defining it after main.

Upvotes: 2

ipinak
ipinak

Reputation: 6029

I think your problem is on this line.

pthread_create(&play, NULL, work_calculation, &parathread);

The correct is this.

pthread_create(&work, NULL, &work_calculation, &parathread);

Apply that for both threads.

Upvotes: 0

Related Questions