问题
I am trying to write a server class with a method that takes a function as an argument and pass in a value (generated inside the server class) to the function for being run inside a thread.
The following is just an example to illustrate what I am trying to do. My goal is to have the Server::runFunctionInThread
general enough that works for methods of different classes as well as for functions that do not belong to any classes. Is this a possible thing to do?
#include <iostream>
#include <thread>
#include <mutex>
#define __PRETTY_FUNCTION__ __FUNCSIG__
std::mutex my_mutex;
// *****************************************************************************************
class Server
{
public:
// With this class method, I am trying to get the function pointer A::FA, B::FB, and FC,
// then generate a value, and ultimately start a thread with the functions and
// the generated value.
template<class Function, class... Args>
void runFunctionInThread(Function f, Args&&... args) {
// This function does other tasks in addition to starting a thread and
// for the sake of this example, they are removed for simplicity.
int valueGeneratedInServer = rand() % 100;
// Pass in the generated value to the function and start a thread with it.
std::thread t(f, std::forward<Args>(args)..., valueGeneratedInServer);
t.detach();
}
};
// *****************************************************************************************
class A
{
public:
void FA(int value) {
std::unique_lock<std::mutex> lock(my_mutex);
std::cout << __PRETTY_FUNCTION__ << " value = " << value << "\n";
}
void run() {
Server s;
s.runFunctionInThread(&A::FA, this);
}
};
// *****************************************************************************************
class B
{
public:
void FB(int value) {
std::unique_lock<std::mutex> lock(my_mutex);
std::cout << __PRETTY_FUNCTION__ << " value = " << value << "\n";
}
void run() {
Server s;
s.runFunctionInThread(&B::FB, this);
}
};
// *****************************************************************************************
// A function that does not belong to any class
void FC(int value) {
std::unique_lock<std::mutex> lock(my_mutex);
std::cout << __PRETTY_FUNCTION__ << " value = " << value << "\n";
}
// *****************************************************************************************
int main()
{
A a;
a.run();
B b;
b.run();
Server s;
s.runFunctionInThread(&FC, 3);
while (true) {};
}
The compiler complains with an error 'std::invoke': no matching overloaded function found
. Could someone kindly shed light on this, please?
回答1:
Before we got your problem, why you don't define the Server
, A
and B
constructors ?
So, your problem is with functions argument. You just sent a function address to your Server
:
s.runFunctionInThread(&A::FA, this);
...
s.runFunctionInThread(&B::FB, this);
...
s.runFunctionInThread(&FC, 3);
And use it wrongly:
std::thread t(f, std::forward<Args>(args)..., valueGeneratedInServer);
Because of non-member functions which don't have a self
parameter. Or if you change your code to this:
template<class Function, class Arg>
void runFunctionInThread(Function f, Arg arg)
{
int valueGeneratedInServer = rand() % 100;
std::thread t(f, valueGeneratedInServer);
t.detach();
}
It won't work with member function, so i suggest you to use std::bind
and std::function
like this:
template<class Function>
void runFunctionInThread(Function f)
{
int valueGeneratedInServer = rand() % 100;
std::thread t(f, valueGeneratedInServer);
t.detach();
}
And use it:
For member functions:
Server s;
s.runFunctionInThread(std::bind(&A::FA, this, std::placeholders::_1));
For non-member functions:
Server s;
s.runFunctionInThread(std::bind(&FC, 3));
来源:https://stackoverflow.com/questions/65352975/a-server-class-taking-any-function-to-run-in-thread-with-passing-a-server-genera