简体   繁体   English

将类的实例传递给pthread_create

[英]Passing instance of a class to pthread_create

My question is somehow related to this post: pthread_create error: 我的问题与帖子有关: pthread_create错误:

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. 为此,我编写了一段代码,并使用了pthread_creat()函数。 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. 现在,DefaultSolver是一个类,从该类实例化2个实例,并应在不同的内核上进行声明,然后通过声明的实例s1和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? 还是在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. 变量(sys1,sys2,... sols1,sols2 ... prec等)是主函数内部的局部变量,因此无法在函数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. 因此,您甚至可能根本不知道线程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. 决定在填充MyThreadParams时应在哪个线程上使用哪个对象的决定,因此,如果可以忽略(threadId == 1),请考虑一下。

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. 您必须决定是否要让线程参数成为System对象和sols等的所有者,或者只应携带对它们的引用/指针并让它们存在于main内部。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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