C++ 为什么pthread_create不在同一个类中使用我的方法?
我想从类中生成一个线程,但似乎找不到使C++ 为什么pthread_create不在同一个类中使用我的方法?,c++,pthreads,C++,Pthreads,我想从类中生成一个线程,但似乎找不到使pthread\u create()满意的正确公式 我的班级看起来像: #ifndef _BFD_ENDPOINT_H_ #define _BFD_ENDPOINT_H_ #include <pthread.h> using namespace std; enum BfdState_e { BFD_STAT_ADMIN_DOWN = 0, BFD_STAT_DOWN, BFD_STAT_INIT
pthread\u create()
满意的正确公式
我的班级看起来像:
#ifndef _BFD_ENDPOINT_H_
#define _BFD_ENDPOINT_H_
#include <pthread.h>
using namespace std;
enum BfdState_e {
BFD_STAT_ADMIN_DOWN = 0,
BFD_STAT_DOWN,
BFD_STAT_INIT,
BFD_STAT_UP };
class BfdEndpoint {
public:
int RxIntvlSet(int);
int TxIntvlSet(int);
int MultSet(int);
int ActvSet(bool);
enum BfdState_e StatusGet();
BfdEndpoint(); // constructor
~BfdEndpoint(); // destructor
public:
//configuration params
int rx; // Rx interval [us]
int tx; // Tx interval [us]
int mult; // multiplier
bool active; // active (1) or passive (0) endpoint
//internal vars
enum BfdState_e status;
pthread_t *RxTh;
pthread_t *TxTh;
//internal methods
int Start();
void *RxSM(void);
void *TxSM(void);
};
#endif
void *BfdEndpoint::RxSM(void)
{
return NULL;
}
int BfdEndpoint::Start(void)
{
int rv = 0;
rv = pthread_create(RxTh,NULL,&BfdEndpoint::RxSM,NULL);
}
而g++
正在发出以下声音:
$ g++ *.cpp -o bfd
bfd.cpp: In member function ‘int BfdEndpoint::Start()’:
bfd.cpp:34:55: error: cannot convert ‘void* (BfdEndpoint::*)()’ to ‘void* (*)(void*)’ for argument ‘3’ to ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’
rv = pthread_create(RxTh,NULL,&BfdEndpoint::RxSM,NULL);
如何执行此操作?
pthread\u create
仅接受常规函数指针(或兼容的)来创建线程。这是C
兼容接口的限制
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
C++11线程抽象接口确实支持类成员函数作为线程运行。当然,成员函数需要一个指向实际对象的指针(这个
指针),因此您必须将它传递给线程
对象
BfdEndpoint object;
std::thread thr{&BfdEndpoint::memfunc, &object, ...};
pthread\u create
只接受常规函数指针(或兼容的)来创建线程。这是C
兼容接口的限制
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
C++11线程抽象接口确实支持类成员函数作为线程运行。当然,成员函数需要一个指向实际对象的指针(这个
指针),因此您必须将它传递给线程
对象
BfdEndpoint object;
std::thread thr{&BfdEndpoint::memfunc, &object, ...};
问题1:
pthread\u create
需要一个以void*
为参数的函数。函数不接受void*
参数
问题2:pthread\u create
需要一个函数指针。在非静态成员函数上应用运算符的地址将生成成员函数指针。成员函数指针不能转换为常规函数指针
解决方案:使用与pthread\u create
期望的函数指针签名匹配的回调函数。这意味着您必须使用自由函数(或静态成员函数)
您可以对自由函数中的对象调用成员函数。一个简单的例子:
void* RxSM(void*) {
static BfdEndpoint object;
object.RxSM();
}
您可能希望对创建线程的对象调用
BfdEndpoint::RxSM
。您可以使用第四个void*arg
参数将该对象传递给回调。问题1:pthread\u create
需要一个将void*
作为参数的函数。函数不接受void*
参数
问题2:pthread\u create
需要一个函数指针。在非静态成员函数上应用运算符的地址将生成成员函数指针。成员函数指针不能转换为常规函数指针
解决方案:使用与pthread\u create
期望的函数指针签名匹配的回调函数。这意味着您必须使用自由函数(或静态成员函数)
您可以对自由函数中的对象调用成员函数。一个简单的例子:
void* RxSM(void*) {
static BfdEndpoint object;
object.RxSM();
}
您可能希望对创建线程的对象调用
BfdEndpoint::RxSM
。您可以使用第四个void*arg
参数将该对象传递给回调。\u BFD\u ENDPOINT\u H
是保留标识符(因为它以下划线开头,后跟大写)。您应该为include-guard提供另一个名称。您与所有成员函数都具有的隐藏参数冲突<代码>作废*RxSM(作废)代码>看起来编译器更像void*RxSM(BfdEndpoint*)代码>否,包含两个连续下划线的标识符也保留BFD\u ENDPOINT\u H
可以。可能重复的\u BFD\u ENDPOINT\u H
是保留标识符(因为它以下划线开头,后跟大写)。您应该为include-guard提供另一个名称。您与所有成员函数都具有的隐藏参数冲突<代码>作废*RxSM(作废)代码>看起来编译器更像void*RxSM(BfdEndpoint*)代码>否,包含两个连续下划线的标识符也保留BFD\u ENDPOINT\u H\uu
就可以了。在惰性加载程序上可能会出现有趣的重复,但是代码如何调用BfdEndpoint::Start
来首先设置pthread
?@user4581301您必须在另一个对象上这样做。如果OP希望在创建线程的同一个对象上调用BfdEndpoint::RxSM
,那么他们必须做一些工作并进一步开发,但是代码首先如何调用BfdEndpoint::Start
来设置pthread
。如果OP希望在创建线程的同一对象上调用BfdEndpoint::RxSM
,那么他们必须做一些工作并进一步开发。