C++ class member function as thread function

When a C++ class member function is used, a this pointer is implicitly passed to the function, and the this pointer points to the object of the class. The function body can call the pointer explicitly or directly access the members in the class.

A callback function is a function called by a pointer. The most commonly used callback function is to create a thread by calling a thread function with a function pointer and multiple parameters passed to the function when creating a thread. Then the general class member function cannot be used as a callback function, because when the library function uses the callback function, it will pass the specified parameters that conform to the callback function declaration to the callback function, and the class member function implicitly contains a this pointer parameter. Therefore, when the class member function is used as a callback function, errors will occur when the parameters do not match. std::thread, its first parameter is a function pointer. In C++, the pointer of its member function cannot be obtained in this way, so an error will be reported.

Solution 1:
Set the member function as a static member function, which does not belong to an object, but belongs to the entire class, without this pointer. However, static member functions cannot use non-static member variables (because it does not have the this pointer of a specific object), and can be called through an object or class pointer.

Solution 2:
Declare the member function as a friend function without the this pointer, but can access the member variables of the class.

Solution three:

Suppose you need to call the non-static member function func2() of the Hack class in a separate thread. No need to directly pass the address of the member function to thr_create(), declare an ordinary function with void* parameters

intermediary(void*), and then call it:

void intermediary(void);

Then create a structure, the structure is defined as follows:

struct A
{
    
    
Hack * p; //类对象指针
void (Hack::*pmf)(); // 成员函数指针
};

Create a structure instance and fill the structure with the desired object address and member function address:

A a; // 结构实例
Hack h; // 创建对象
//填充结构
a.p = & h;
a.pmf = &Hack::func2; // 取成员函数地址

Now go back and implement the intermediate() function:

void *intermediary(void* ptr)
{
    
    
 A* pa=static_cast < A* > (ptr); // 强制转换 p 为 A*
 Hack* ph=pa->p; // 从A中析取Hack对象地址
 void (Hack::*pmf)()=pa->pmf; // 析取 ptr 到成员函数
 (ph->*pmf)(); // 调用成员函数
}

Finally, pass the address of intermediate() to thr_create():

pthread_create (&ptid, NULL, intermediary, (void *)&a );

pthread_create() calls the function intermediate() and passes the address of A to it. intermediary() then expands structure A from its pointer parameter and calls the desired member function. This indirect way

Processing can safely launch member functions in a separate thread, even if the thread library does not support member functions. If you need to call different member functions of different classes, you can convert structure A into a class template, and change the function

intermediary() is converted into a function template. So the compiler will automatically generate most of the boilerplate code.

Guess you like

Origin blog.csdn.net/weixin_45146520/article/details/109267486