如何在类中使用 pthread_mutex 及其函数?

发布于 2024-11-09 06:30:49 字数 1602 浏览 4 评论 0原文

我已经搜索了很多小时来寻找解决方案,但找不到简单的答案。 我有一个使用 pthreads 的类。实际的函数指针在类中是静态的,我需要锁定互斥锁,因为到目前为止我得到了“奇怪”的结果(参数未正确传递)。

然而,pthread_mutex_lock和unlock在给线程的函数内不起作用,因为它是在静态成员函数中,但我不能让该函数成为非静态的,因为它不能在类内部工作,而且我不能将它移到类之外类,因为它将无法访问所需的信息。

下面的代码应该解释:

class Fight{

     pthread_mutex_t thread_mutex;
     static void *thread_run_fighter(void *temp);

  public:

    Fight();
    bool thread_round(Individual &a, int a_u, Individual &b, int b_u);
    std::vector<Individual> tournament();
  };

和 cpp 文件:

    Fight::Fight(){
       thread_mutex = PTHREAD_MUTEX_INITIALIZER;
    }

    bool Fight::thread_round(Individual &a, int a_u, Individual &b, int b_u){

    if (a.saved and b.saved){
       a.uniform = a_u;
       b.uniform = b_u;
       Individual *one = &a;
       Individual *two = &b;      
       pthread_t a_thread, b_thread;
       int a_thread_id, b_thread_id;
       a_thread_id = pthread_create(&a_thread,NULL,Fight::thread_run_fighter,(void*) one);
       b_thread_id = pthread_create(&b_thread,NULL,Fight::thread_run_fighter,(void*) two);

       pthread_join( a_thread, NULL);
       pthread_join( b_thread, NULL); 
       return true;
    }
    else{
       return false;
    }
   }

   void *Fight::thread_run_fighter(void *temp){

     Individual *indiv;
     indiv = (class Individual*)temp;
     pthread_mutex_lock( &thread_mutex );
     indiv->execute(indiv->uniform);
     pthread_mutex_unlock( &thread_mutex );

   }

如果有人能对此有所启发,我将非常感激。我已经被困了几个小时了,但找不到任何信息。 谢谢你!

I have searched for many hours for a solution, but cannot find an easy answer.
I got a class, which uses pthreads. The actual function pointer is static within the class, and I need to lock on a mutex, because so far I get "weird" results (parameters not being passed correctly).

However the pthread_mutex_lock and unlock will not work within the function given to the thread, because it is in a static member function, yet I cannot have the function non static because it won't work inside the class, and I cannot move it outside the class, because it won't be able to access required info.

The following code should explain:

class Fight{

     pthread_mutex_t thread_mutex;
     static void *thread_run_fighter(void *temp);

  public:

    Fight();
    bool thread_round(Individual &a, int a_u, Individual &b, int b_u);
    std::vector<Individual> tournament();
  };

And the cpp file:

    Fight::Fight(){
       thread_mutex = PTHREAD_MUTEX_INITIALIZER;
    }

    bool Fight::thread_round(Individual &a, int a_u, Individual &b, int b_u){

    if (a.saved and b.saved){
       a.uniform = a_u;
       b.uniform = b_u;
       Individual *one = &a;
       Individual *two = &b;      
       pthread_t a_thread, b_thread;
       int a_thread_id, b_thread_id;
       a_thread_id = pthread_create(&a_thread,NULL,Fight::thread_run_fighter,(void*) one);
       b_thread_id = pthread_create(&b_thread,NULL,Fight::thread_run_fighter,(void*) two);

       pthread_join( a_thread, NULL);
       pthread_join( b_thread, NULL); 
       return true;
    }
    else{
       return false;
    }
   }

   void *Fight::thread_run_fighter(void *temp){

     Individual *indiv;
     indiv = (class Individual*)temp;
     pthread_mutex_lock( &thread_mutex );
     indiv->execute(indiv->uniform);
     pthread_mutex_unlock( &thread_mutex );

   }

I would be really grateful if anyone could shed some light into this. I have been stuck for some hours now, and I could not find any info whatsoever.
Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

私野 2024-11-16 06:30:49

我认为“不起作用”的意思是它无法编译,因为您尝试在 static 成员函数中使用实例成员。

但更大的问题是你为什么要尝试使用线程来实现这个目的?

无论如何,您拥有的线程函数完全受互斥体保护 - 通过简单地调用

a.execute(a.uniform);
b.execute(b.uniform);

而不是旋转线程然后等待它们完成,您将获得相同(或更好)的性能。


但是,如果您确实想使用线程(也许您正在学习它们)并且希望静态成员函数能够处理实例成员,那么这里有一些指针。要使其正常工作,您需要以某种方式将 Fight 对象的实例传递给 static 线程函数:

// somewhere in `class Fight` definition:
//
// a structure that will let you pass a Fight* instance pointer
//  along with an Individual* to work on in the the
//  thread function

struct context {
    Fight* me;
    Individual* indiv;
};



// ...

// in Fight::thread_round():
//  package up data to pass to the thread function
context one = {this, &a };  // instead of Individual *one = &a;
context two = {this, &b };  // instead of Individual *two = &b;

最后,Fight::thread_run_fighter()

void *Fight::thread_run_fighter(void *temp)
{
    // pull out the Fight object instance and the Individual
    //  object to work on
    context* ctx = (context*) temp;
    Individual *indiv = ctx->indiv;
    Fight* me = ctx->me;

    // do the work (in a pretty serialized fashion, unfortunately)
    pthread_mutex_lock( &me->thread_mutex );
    indiv->execute(indiv->uniform);
    pthread_mutex_unlock( &me->thread_mutex );

    return 0;
}

By 'doesn't work' I assume you mean it won't compile since you're trying to use an instance member in a static member function.

But the bigger question is why are you trying to use threads for this?

The thread function you have is entirely protected by the mutex anyway - you'll get the same (or better) performance by simply calling

a.execute(a.uniform);
b.execute(b.uniform);

instead of spinning up the threads then waiting for them to complete.


But if you really want to use threads (maybe you're learning about them) and you want your static member function to be able to deal with instance members, here are some pointers. To get that to work, you'll need to somehow pass an instance of the Fight object to the static thread function:

// somewhere in `class Fight` definition:
//
// a structure that will let you pass a Fight* instance pointer
//  along with an Individual* to work on in the the
//  thread function

struct context {
    Fight* me;
    Individual* indiv;
};



// ...

// in Fight::thread_round():
//  package up data to pass to the thread function
context one = {this, &a };  // instead of Individual *one = &a;
context two = {this, &b };  // instead of Individual *two = &b;

Finally, Fight::thread_run_fighter():

void *Fight::thread_run_fighter(void *temp)
{
    // pull out the Fight object instance and the Individual
    //  object to work on
    context* ctx = (context*) temp;
    Individual *indiv = ctx->indiv;
    Fight* me = ctx->me;

    // do the work (in a pretty serialized fashion, unfortunately)
    pthread_mutex_lock( &me->thread_mutex );
    indiv->execute(indiv->uniform);
    pthread_mutex_unlock( &me->thread_mutex );

    return 0;
}
时常饿 2024-11-16 06:30:49

我想问的第一个问题:您需要可移植代码吗?如果是,切勿将 C++ 函数传递给 pthread_create。原因: pthread_create 的接口需要声明为 extern "C" 的函数,并且您很幸运(感谢 x86:) )静态成员方法适合于此,但不能保证在其他平台或编译器上也同样适用。

第二,您在互斥体创建后调用了 thread_mutex = PTHREAD_MUTEX_INITIALIZER; ,据我记得标准说这仅在初始化时允许。

最后,不允许使用静态方法的 pthread_mutex_lock( &thread_mutex ) ,因为静态方法无法访问对象的非静态成员,因此您需要将指针传递给对象。您可以将 pthread_mutex_t thread_mutex;void *thread_run_fighter(void *temp); 声明为全局,因为我认为在这种情况下这将是最简单的方法。

还有一些注意事项:boost::threads 怎么样?我认为使用它而不是创建自己的解决方案会更好......

The first question which I'd like to ask: do you need portable code? If yes, never pass C++ function to pthread_create. The reason: interface for pthread_create requires function declared as extern "C", and you are lucky (thanks to x86:) ) that static member method suits for this, but there is no guarantee that the same will be on other platform or compilers.

The second, you have called thread_mutex = PTHREAD_MUTEX_INITIALIZER; after mutex creation, as far as I remember standard say that this is allowed on initialization only.

And finally, pthread_mutex_lock( &thread_mutex ) withing static method will not allowed because static method does not have access to object's non-static members, so you need to pass a pointer to you object. You may declare pthread_mutex_t thread_mutex; and void *thread_run_fighter(void *temp); as global, as I see it will be the simplest way in this case.

And some notes: what about boost::threads? I think it will be better to use it instead of creating your own solution...

倾听心声的旋律 2024-11-16 06:30:49

我认为您错过的只是使用 &indiv->thread_mutex 而不是省略 indiv-> 对象。

编辑:请注意,使用静态转换可能比使用 C 风格的“霰弹枪”转换更好:Individual *indiv = static_cast(temp);

I think all you missed was to use &indiv->thread_mutex instead of omitting the indiv-> object.

EDIT: Do note that it's probably better to use a static cast rather than the C-style "shotgun" cast: Individual *indiv = static_cast<Individual*>(temp);

唠甜嗑 2024-11-16 06:30:49

在静态 thread_run_fighter 内部,您正在使用非静态 thread_mutex。 thread_mutex 在使用之前必须使用 pthread_mutex_init 创建。

inside of the static thread_run_fighter you are using the non static thread_mutex. thread_mutex must be created with pthread_mutex_init prior to it's use.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文