如何在类中使用pthread_mutex及其函数?
How to use pthread_mutex and it's functions within a class?
我花了很多小时寻找解决方案,但找不到简单的答案。我有一个类,它使用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 );
}
如果有人能对此有所了解,我将不胜感激。我已经被困了几个小时,找不到任何信息。非常感谢。
"不起作用"我认为你的意思是它不会编译,因为你试图在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;
}
我想问的第一个问题是:你需要可移植代码吗?如果是,则永远不要将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::线程怎么样?我认为使用它会更好,而不是创建自己的解决方案。。。
我想您错过的只是使用&indiv->thread_mutex
,而不是省略indiv->
对象。
编辑:请注意,使用静态铸造可能比C风格的"霰弹枪"铸造更好:Individual *indiv = static_cast<Individual*>(temp);
在静态thread_run_fighter
内部使用非静态thread_mutex
。在使用thread_mutex之前,必须使用pthread_mutex_init创建它。
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 有什么理由C++ 11+ std::mutex 应该声明为全局变量,而不是作为函数参数传递到 std::thread 中
- 没有用于初始化 std::lock_guard<std::mutex 的匹配构造函数>
- 为什么使用 std::mutex 的函数会对 pthread_key_create 的地址进行空检查?
- 从C 中的Mutex锁定代码中的函数返回的好方法
- 以std::mutex作为参数对成员函数进行线程处理
- 如何 std::mutex::锁定直到函数返回
- 在boost::mutex构造函数中同时写入同一内存区域可能存在错误
- <mutex> 如何在没有互斥体实例的情况下lock_guard构造函数进行编译?
- 可变boost::mutex可以分离锁和等待函数
- Boost::mutex - 是否可以将其锁定在一个类函数中并在另一个类函数上解锁