Boost logo

Boost Users :

Subject: [Boost-users] Use Boost thread and store results of function into object's local variable.
From: Damian (dfermin_at_[hidden])
Date: 2011-07-23 15:28:12


Hello.

I'm a new to Boost and the listserv so please forgive my ignorance if my
question is obvious.
I have found the Boost documentation and example difficult to use for my
needs (perhaps I'm just not using the correct packages).

I have a vector of objects each of which needs to do so calculations.
Each vector element can run independently and doesn't rely on anything
other than its own private variables.

I'd like to launch N threads (where N can vary from 1...8 let's say) and
pass to each thread 1 element of the vector. Within the threads, each
object crunches its numbers and stores its result in its local variable.

I've got some code here but it won't compile. I get this error message:
"cannot call member function ‘void PSMClass::process()’ without object"

I think the problem is that I'm not passing the vector element itself
but rather a pointer to it (?).
Perhaps this isn't the best approach, I don't know.

Can anyone help me out?

Thanks in advance for any and all help.

################################################################

#include <iostream>
#include <vector>
#include <cstdlib>
#include <boost/thread.hpp>
#include <boost/bind.hpp>

using namespace std;

class PSMClass;

class PSMClass {
private:
int id;
double x;
double y;

public:
PSMClass(){}; // default ctor
PSMClass(int i, double a); // constructor

void process();
int getId() { return id; }
double getX(){ return x; }
double getY(){ return y; }
void innerFunc(double r);

};

PSMClass::PSMClass(int i, double a) {
id = i;
x = a;
y = 0;
}

// just some function that we want to run in parallel
void PSMClass::process() {
double r = 0;
double odd = 0;

int STOP = id * 10000000;
for(int i = 0; i < STOP; i++) {
r += 1;

// this is just some random code I through in to make the process
// CPU-intensive yet slow enough for me to monitor it on 'top'
odd = (double)rand() * sin( (double)rand() );
}
innerFunc(r);
odd = 0;
}

// just another function to obfuscate matters
void PSMClass::innerFunc(double r) {
y = r;
}

/*******************************************************************************
*
* Main Function
*
******************************************************************************/
int main(int argc, char* argv[]) {

PSMClass *curPSM = NULL;
vector<PSMClass> PSM_vec;
vector<PSMClass>::iterator v;

double r;
int N = 10;

for(int i = 0; i < N; i++) {
r = (double) (rand() % N + 1000);

curPSM = new PSMClass(i, r);
PSM_vec.push_back(*curPSM);
delete(curPSM); curPSM = NULL;
}

cout << "Initial states:\n";
cout << "id\tx\ty\n";
for(v = PSM_vec.begin(); v != PSM_vec.end(); v++) {
cout << v->getId() << "\t" << v->getX() << "\t" << v->getY() << endl;
}
cout << endl;

// we want to limit TG to just 2 threads. In the final program the user
// will give as input at the command line how many threads the program
// should use.
int NUM_THREADS = 2;
boost::thread_group *TG = NULL;
TG = new boost::thread_group;

for(v = PSM_vec.begin(); v != PSM_vec.end(); v++) {

TG->create_thread( boost::bind( &PSMClass::process(), boost::ref(*v) ) );

if( (signed)TG->size() == NUM_THREADS ) {
TG->join_all();
// destroy all the threads you created
delete(TG); TG = NULL;
TG = new boost::thread_group;
}
}
cout << endl;

TG->join_all(); // collect the remaining threads together
delete(TG); TG = NULL;

// At this point v->getY() should return the value that was computed
// within the threads.
cout << "Final states:\n";
cout << "id\tx\ty\n";
for(v = PSM_vec.begin(); v != PSM_vec.end(); v++) {
cout << v->getId() << "\t" << v->getX() << "\t" << v->getY() << endl;
}
cout << endl;

return 0;
}
################################################################


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net