将类的实例传递给pthread_create

时间:2014-09-11 15:29:25

标签: c++ multithreading c++11 pthreads

我的问题与这篇文章有某种关系: pthread_create error:

我试图在不同的核心上调用解算器的多个实例(也许是一个类)。为此我写了一个代码并使用了pthread_creat()函数。以下是我的努力:

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);
}}

现在DefaultSolver是一个类,我实例化2个实例,声明应该在不同的核上完成,然后我通过声明的实例s1和s2使用该类的不同函数。以下是我调用此函数的代码。以下是剩下的代码:

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);}

以下是我尝试制作时的错误:

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

有什么办法可以解决吗?或者在c ++ 11中还有其他简单方法吗?

1 个答案:

答案 0 :(得分:2)

变量(sys1,sys2,... sols1,sols2 ... prec等)是主函数内的局部变量,因此在函数MultiThread中无法访问它们。 [编辑:通常只能将一个参数传递给某个帖子。如果你想传递多个参数,你必须创建一个“容器”来保存它们 - 一个类或一个记录。]

丑陋的解决方案是将全局变量排除在外。

更常见的方法是创建一个包含线程内所需数据的类或记录,为每个线程创建一个实例并将该对象作为参数传递。所以你甚至可能不知道你的线程ID。

快速入侵:

创建容器类:

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
};

在你的线程函数中,将参数强制转换为该类,并使用其值而不是您尝试从此处访问的变量。

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
}

在填充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]));
}

您必须决定是否希望线程参数成为System对象和sol等的所有者,或者只应携带对它们的引用/指针,并让它们存在于main中。