带参数的Pthread成员函数

时间:2014-04-22 01:52:26

标签: c++ pthreads

我试图在课堂上使用pthreads。我已经读过使用成员函数的线程的最佳解决方案是定义一个静态辅助函数并从内部调用线程函数。但这需要一个'这个'指针作为参数传递给pthread_create。如果我的原始线程函数已经有参数,我该如何实现呢?有没有办法将多个参数传递给pthread_create?

2 个答案:

答案 0 :(得分:3)

pthread_create定义为

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

因此,它需要一个函数指针,例如

void *myfunction(void *argument)

void* argument

如果要在课堂上使用它,请执行以下操作:

  1. 使用签名定义静态方法:static void *myMethod(void *argument)
  2. 从对象(非静态)方法调用pthread_create,并将this作为arg参数传递。
  3. 静态方法的实现必须将void *argument强制转换为类的指针( sort-of-this ),可用于调用其他(非静态)对象的方法。
  4. 现在,根据您需要在线程中执行的其他操作以及将参数传递给它们,您可以执行以下操作:

    1. 不是传递this中的arg,而是传递可以包含this和所有参数的其他类型。
    2. 或者,或许更多的OO,在调用pthread_create之前,可以在线程函数所需的那些参数中创建可以在对象中设置的类的属性,并且可以从排序 - 得到这
    3. 更具体

      class MyThread {
      public:
      
         MyThread(int _argument): mArgument(_argument) { }
      
         void start() {
             pthread_create(&mThreadId, 0,&MyThreadClass::threadMethod, this);
         }
      
         void doThings(int x) {
             // something to be done in the thread.
         }
      
         static void *threadMethod(void *arg) {
             MyThread *_this=static_cast<MyThread *>(arg);
             _this->doThings(_this->getArgument());
         }
      
         int getArgument() const {
             return mArgument;
         }
      
      private:
         pthread_t mThreadId;
         int mArgument;
      };
      

      可以称为:

      MyThread thread(10);
      thread.start();
      

答案 1 :(得分:2)

您不能将多个参数传递给pthread_create,但您可以将多个参数打包到专门为打包参数而创建的struct中。将struct&#34;私有&#34;通过在cpp文件中而不是在标头中定义它来实现。将该结构的指针传递给pthread_create,然后&#34;解包&#34;它在助手中调用成员函数。

让我们假设线程实现是一个成员函数threadRun,定义如下:

int MyClass::threadRun(int arg1, string arg2) {
    ...        // Do useful work
    return 42; // Return an important number
}

要调用此功能,请按以下方式定义thread_args struct

struct thread_args {
    MyClass *instance;
    int arg1;
    string arg2;
};

现在您的帮助函数可以定义如下:

void* thread_helper(void *voidArgs) {
    thread_args *args = (thread_args*)voidArgs;
    int res = args->instance->threadRun(args->arg1, args->arg2);
    return new int(res); // Return an `int` pointer to pass back thread runner's results
}

启动线程的函数可能如下所示:

...
MyClass runner;
thread_args args;
args.instance = &runner;
args.arg1 = 123;
args.arg2 = "hello";
pthread_t thread_id;
int s = pthread_create(&thread_id, NULL, &thread_helper, &args);