如何在类中使用 pthread_mutex 及其函数?
我已经搜索了很多小时来寻找解决方案,但找不到简单的答案。 我有一个使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为“不起作用”的意思是它无法编译,因为您尝试在
static
成员函数中使用实例成员。但更大的问题是你为什么要尝试使用线程来实现这个目的?
无论如何,您拥有的线程函数完全受互斥体保护 - 通过简单地调用
而不是旋转线程然后等待它们完成,您将获得相同(或更好)的性能。
但是,如果您确实想使用线程(也许您正在学习它们)并且希望静态成员函数能够处理实例成员,那么这里有一些指针。要使其正常工作,您需要以某种方式将 Fight 对象的实例传递给
static
线程函数:最后,
Fight::thread_run_fighter()
: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
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:Finally,
Fight::thread_run_fighter()
:我想问的第一个问题:您需要可移植代码吗?如果是,切勿将 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 declarepthread_mutex_t thread_mutex;
andvoid *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...
我认为您错过的只是使用
&indiv->thread_mutex
而不是省略indiv->
对象。编辑:请注意,使用静态转换可能比使用 C 风格的“霰弹枪”转换更好:
Individual *indiv = static_cast(temp);
I think all you missed was to use
&indiv->thread_mutex
instead of omitting theindiv->
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);
在静态
thread_run_fighter
内部,您正在使用非静态thread_mutex
。 thread_mutex 在使用之前必须使用 pthread_mutex_init 创建。inside of the static
thread_run_fighter
you are using the non staticthread_mutex
. thread_mutex must be created with pthread_mutex_init prior to it's use.