【问题标题】:Pthread member function with arguments带参数的 Pthread 成员函数
【发布时间】:2014-04-22 01:52:26
【问题描述】:

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

【问题讨论】:

    标签: c++ pthreads


    【解决方案1】:

    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 转换为可用于调用其他(非静态)方法的类的指针(a sort-of-this)对象。

    现在,根据您需要在线程中执行的其他操作并将参数传递给它们,您可以做几件事:

    1. 不要在arg 中传递this,而是传递一个可以包含this 和所有参数的不同类型。
    2. 或者,也许更多的面向对象,使线程功能所需的那些参数,可以在调用 pthread_create 之前在对象中设置的类的属性,并且可以从 sort-of-this

    更具体

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

    【讨论】:

      【解决方案2】:

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

      假设线程实现是一个成员函数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);
      

      【讨论】:

      • @WaseemAhmadNaeem 是的,这是一个错字 - 答案中的其他任何地方都没有 targs。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-16
      • 1970-01-01
      相关资源
      最近更新 更多