Reputation: 3
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 ,¶thread);
pthread_create(&work, NULL, play_calculation, ¶thread);
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
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
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
Reputation: 4616
Move the definition of typedef struct {} s_param at the beginning of the file.
Upvotes: 0
Reputation: 254701
The struct
needs to be defined before you instantiate it in main
; you are defining it after main
.
Upvotes: 2
Reputation: 6029
I think your problem is on this line.
pthread_create(&play, NULL, work_calculation, ¶thread);
The correct is this.
pthread_create(&work, NULL, &work_calculation, ¶thread);
Apply that for both threads.
Upvotes: 0