将带有任意数量参数的任何 class 成员函数传递给 class 之外的函数
Passing any class member function with any number of arguments to a function outside the class
Remy posted a great solution to pass any function with any number of arguments to std::thread
, 。我想知道如何将它用于 class 成员函数。
#include <iostream>
#include <thread>
#include <mutex>
#define __PRETTY_FUNCTION__ __FUNCSIG__
std::mutex my_mutex;
template<class Function, class... Args>
void runFunctionInThread(Function f, Args&&... args) {
// Beside starting a thread, this function performs other
// task using the function and its arguments.
std::thread t(f, std::forward<Args>(args)...);
t.detach();
}
class MyClass
{
public:
MyClass() {};
void myFunc1() { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << "\n"; }
void myFunc2(int value) { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << "value is " << value << "\n"; }
void myFunc3(int value1, int value2) { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << "value1+value2 is " << value1 + value2 << "\n"; }
void manager() {
void (MyClass::*f1)() = &MyClass::myFunc1;
void (MyClass::*f2)(int) = &MyClass::myFunc2;
void (MyClass::*f3)(int,int) = &MyClass::myFunc3;
runFunctionInThread(f1);
runFunctionInThread(f2, 2);
runFunctionInThread(f3, 3, 3);
}
};
void isolatedFunc1() { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << "\n"; }
void isolatedFunc2(int value) { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << " value is " << value << "\n"; }
void isolatedFunc3(int value1, int value2) { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << " value1+value2 is " << value1 + value2 << "\n"; }
int main()
{
runFunctionInThread(&isolatedFunc1); // Works flawlessly
runFunctionInThread(&isolatedFunc2, 2); // Works flawlessly
runFunctionInThread(&isolatedFunc3, 3, 3); // Works flawlessly
MyClass m;
m.manager();
}
如果你想调用成员函数,你也需要将对象传递给 std::thread
:
void manager() {
//...
runFunctionInThread(f1, this);
runFunctionInThread(f2, this, 2);
runFunctionInThread(f3, this, 3, 3);
}
注意:
我注意到你分离了你的线程。然后您需要手动确保它们在您的程序结束之前已经结束,或者如果它们仍然是 运行.
,您将在程序退出时感到惊讶。
通常更容易将 运行 个线程保存在一个容器中(如 std::list<std::thread>
),然后再 join()
它们。在 C++20 中,您甚至可以 std::list<std::jthread>
让它们在容器被销毁时自动加入。
Remy posted a great solution to pass any function with any number of arguments to std::thread
,
#include <iostream>
#include <thread>
#include <mutex>
#define __PRETTY_FUNCTION__ __FUNCSIG__
std::mutex my_mutex;
template<class Function, class... Args>
void runFunctionInThread(Function f, Args&&... args) {
// Beside starting a thread, this function performs other
// task using the function and its arguments.
std::thread t(f, std::forward<Args>(args)...);
t.detach();
}
class MyClass
{
public:
MyClass() {};
void myFunc1() { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << "\n"; }
void myFunc2(int value) { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << "value is " << value << "\n"; }
void myFunc3(int value1, int value2) { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << "value1+value2 is " << value1 + value2 << "\n"; }
void manager() {
void (MyClass::*f1)() = &MyClass::myFunc1;
void (MyClass::*f2)(int) = &MyClass::myFunc2;
void (MyClass::*f3)(int,int) = &MyClass::myFunc3;
runFunctionInThread(f1);
runFunctionInThread(f2, 2);
runFunctionInThread(f3, 3, 3);
}
};
void isolatedFunc1() { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << "\n"; }
void isolatedFunc2(int value) { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << " value is " << value << "\n"; }
void isolatedFunc3(int value1, int value2) { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << " value1+value2 is " << value1 + value2 << "\n"; }
int main()
{
runFunctionInThread(&isolatedFunc1); // Works flawlessly
runFunctionInThread(&isolatedFunc2, 2); // Works flawlessly
runFunctionInThread(&isolatedFunc3, 3, 3); // Works flawlessly
MyClass m;
m.manager();
}
如果你想调用成员函数,你也需要将对象传递给 std::thread
:
void manager() {
//...
runFunctionInThread(f1, this);
runFunctionInThread(f2, this, 2);
runFunctionInThread(f3, this, 3, 3);
}
注意: 我注意到你分离了你的线程。然后您需要手动确保它们在您的程序结束之前已经结束,或者如果它们仍然是 运行.
,您将在程序退出时感到惊讶。通常更容易将 运行 个线程保存在一个容器中(如 std::list<std::thread>
),然后再 join()
它们。在 C++20 中,您甚至可以 std::list<std::jthread>
让它们在容器被销毁时自动加入。