简体   繁体   中英

Passing instance of a class to pthread_create

My question is somehow related to this post: pthread_create error:

I am trying to call a multiple instances of a solver (which is a class perhaps) on different cores. For this I wrote a chuck of code and used pthread_creat() function. Following is my effort:

void *MultiThread(void *threadid)
{ 

 long tid;
 tid = (long)threadid;


if(tid==0)
{
    cout<< "load thread number "<< tid;
    DefaultSolver s1(sys1,prec);
    s1.time_limit=time_limit;
    s1.trace= true; 
    sols1=s1.solve(pair2.first);
    cout << "number of solutions from solver 1=" << sols1.size() << endl;
    cout << "cpu time used=" << s1.time << "s."<< endl;
    cout << "number of cells=" << s1.nb_cells << endl;


pthread_exit(NULL);
}

if(tid==1)
{


    cout<< "load thread number "<< tid; 
    DefaultSolver s2(sys2,prec);
    s2.time_limit=time_limit;
    s2.trace=true;
    sols2=s2.solve(pair2.second);
    cout << "number of solutions from solver 2=" << sols2.size() << endl;
    cout << "cpu time used=" << s2.time << "s."<< endl;
    cout << "number of cells=" << s2.nb_cells << endl;
    pthread_exit(NULL);
}}

Now DefaultSolver is a class from which I am instantiating 2 instances and declaration should be done on different cores, and then I am using different functions of that class through the declared instances s1 and s2. Following is the code where I am calling this function. Following is the remaining piece of code:

double convert(const char* argname, const char* arg) {
char* endptr;
double val = strtod(arg,&endptr);
if (endptr!=arg+strlen(arg)*sizeof(char)) {
    stringstream s;
    s << "\"" << argname << "\" must be a real number";
    ibex_error(s.str().c_str());
 }
    return val;
}

int main(int argc, char** argv)

{

pthread_t threads[NUM_THREADS];
int rc;
int i;


try{

    // check the number of arguments
    if (argc<4) {
        ibex_error("usage: defaultsolver filename prec timelimit");
    }



    vector<IntervalVector> sols1, sols2, sols3,  sols4;

    System sys1(argv[1]);
    System sys2(sys1, System::COPY);
    System sys3(sys1, System::COPY);
    System sys4(sys1, System::COPY);

    double prec =        convert("prec", argv[2]);
    double time_limit = convert("timelimit",argv[3]);
    double bisect = convert("bisect",argv[4]);








   pair<IntervalVector,IntervalVector>  pair1=sys1.box.bisect(bisect);
   pair<IntervalVector,IntervalVector>  pair2 = pair1.first.bisect(bisect);
   pair<IntervalVector,IntervalVector>  pair3= pair1.second.bisect(bisect);





  for( i=0; i < NUM_THREADS; i++ ){
  cout << "main() : creating thread, " << i << endl;
  rc = pthread_create(&threads[i], NULL, 
                      MultiThread, (void *)i);

  if (rc){
     cout << "Error:unable to create thread," << rc << endl;
     exit(-1);
    }
  }

 pthread_exit(NULL);}

And following is the error when I am trying to make it:

parallel2.cpp: In function ‘void* MultiThread(void*)’:
parallel2.cpp:29:26: error: ‘sys1’ was not declared in this scope
parallel2.cpp:29:31: error: ‘prec’ was not declared in this scope
parallel2.cpp:30:17: error: ‘time_limit’ was not declared in this scope
parallel2.cpp:32:3: error: ‘sols1’ was not declared in this scope
parallel2.cpp:32:18: error: ‘pair2’ was not declared in this scope
parallel2.cpp:50:20: error: ‘sys2’ was not declared in this scope
parallel2.cpp:50:25: error: ‘prec’ was not declared in this scope
parallel2.cpp:51:17: error: ‘time_limit’ was not declared in this scope
parallel2.cpp:53:3: error: ‘sols2’ was not declared in this scope
parallel2.cpp:53:18: error: ‘pair2’ was not declared in this scope
parallel2.cpp:64:20: error: ‘sys3’ was not declared in this scope
parallel2.cpp:64:25: error: ‘prec’ was not declared in this scope
parallel2.cpp:65:17: error: ‘time_limit’ was not declared in this scope
parallel2.cpp:67:3: error: ‘sols3’ was not declared in this scope
parallel2.cpp:67:18: error: ‘pair3’ was not declared in this scope
parallel2.cpp:80:20: error: ‘sys4’ was not declared in this scope
parallel2.cpp:80:25: error: ‘prec’ was not declared in this scope
parallel2.cpp:81:17: error: ‘time_limit’ was not declared in this scope
parallel2.cpp:83:3: error: ‘sols4’ was not declared in this scope
parallel2.cpp:83:18: error: ‘pair3’ was not declared in this scope

Is there any way to fix it? or is there any other easy way in c++11?

The variables (sys1, sys2, ... sols1, sols2... prec etc.) are local variables inside your main function, so they are not accessible in your function MultiThread. [ Edit : Usually you can only pass one parameter to a thread. If you want to pass multiple parameters you have to create a "container" holding them - a class or a record.]

The ugly solution is to make global variables out of them.

The more common approach is to create a class or record holding all data you need inside your thread, create one instance for each thread and pass that object as the parameter. So you probably even don't neet to know your thread id.

Quick hack:

Create a container class:

class MyThreadParams
{
public:
    // you can add getters/setters and hide the member variables if you want
    long threadId; //still needed?
    System *pSys;
    double prec;
    double time_limit;
    // further values /objects you need
};

In your thread function, cast the parameter to that class and use its values instead of your variables you tried to access from here.

void *MultiThread(void *threadParams)
{
    MyThreadParams* pParams = reinterpret_cast<MyThreadParams*>(threadParams);
    cout<< "load thread number "<< tid;
    DefaultSolver solver(pParams->sys1, pParams->prec);
    solver.time_limit = pParams->time_limit;
    //and so on
}

The decision which objects shall be used for whicht thread has been done in main when filling MyThreadParams, so you if (threadId == 1) can be ommitted, think.

int main(int argc, char** argv)
{
    ....
    MyThreadParams threadParams[NUM_THREADS];
    ....
    // fill params for 1st thread
    threadParams[0].threadId = 0;
    threadParams[0].pSys = &sys1;
    threadParams[0].prec = convert("prec", argv[2]);
    threadParams[0].time_limit := convert("timelimit",argv[3]);
    // further values /objects you need

    // fill params for 2nd thread
    threadParams[1].threadId = 1;
    threadParams[2].pSys = &sys2;
    threadParams[3].prec = convert("prec", argv[2]);
    // and so on

    rc = pthread_create(&threads[i], NULL, 
                  MultiThread, reinterpret_cast<void *>(&threadParams[i]));
}

You have to decide whether you want the thread params to be the owner of the System object and the sols etc. or should only carry references/pointer to them and let the exist inside main.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM