首页 > 解决方案 > 将具有任意数量参数的任何类成员函数传递给类外的函数

问题描述

Remy在这里发布了一个很好的解决方案,可以将带有任意数量参数的任何函数传递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();

}

标签: c++multithreadingclassvariadic-functions

解决方案


如果要调用成员函数,则还需要将对象传递给std::thread

void manager() {
    //...
    runFunctionInThread(f1, this);
    runFunctionInThread(f2, this, 2);
    runFunctionInThread(f3, this, 3, 3);
}

注意:我注意到您分离了线程。然后,您需要手动确保它们在您的程序执行之前已经结束,或者如果它们仍在运行,您会在程序退出时感到意外。

将正在运行的线程保存在容器中(如 a std::list<std::thread>)通常更容易,join()稍后再保存。在 C++20 中,您甚至可以让std::list<std::jthread>它们在容器被销毁时自动加入。


推荐阅读