I'm assuming there's something very simple I'm missing about std::async. I'm trying to run 2 void methods asynchronously, with no return values.
#include <future>
class AsyncTestClass {
public:
void Initialize()
{
std::async(&AsyncTestClass::AsyncMethod1);
std::async(&AsyncTestClass::AsyncMethod2);
}
void AsyncMethod1()
{
//time consuming operation
}
void AsyncMethod2()
{
//time consuming operation
}
};
But get an error when calling my AsyncMethod1 or AsyncMethod2 within std:async:
Substitution failed: type 'typename std:conditional<sizeof....(ArgTypes) == 0, std::_Invoke_traits_Zero<void, typename std::decay.....is ill formed with _Fty = void (AsyncTestClass::*)(), _ArgTypes =
What is the proper usage of std:async with void, parameterless methods? The examples I see seem similar to how I'm using it, but it's not working for me.
AsyncTestClass::AsyncMethod1, being a non-static member function, can only be called if an instance of AsyncTestClass is supplied. You probably meant this:
std::async(&AsyncTestClass::AsyncMethod1, this)
This creates a std::future object whose value will be obtained by evaluating this->AsyncMethod1().
By the way, the return value of std::async should be assigned to a variable, otherwise the call will block. See std::async won't spawn a new thread when return value is not stored. If you have C++20, the compiler will catch this for you thanks to [[nodiscard]].
Related
The below given code is taken from LevelDB. I am giving two blocks of code for better understanding. I am unable to understand what is happening.
ThreadState is a structure and I have written here to make it easy for the reader.
struct ThreadState {
int tid; // 0..n-1 when running in n threads
Random rand; // Has different seeds for different threads
Stats stats;
SharedState* shared;
ThreadState(int index)
: tid(index),
rand(1000 + index) {
}
};
Is the marked code below an object instantiation of class Benchmark? What is happening in the marked code below?
void Run() {
PrintHeader();
Open();
const char* benchmarks = FLAGS_benchmarks;
while (benchmarks != NULL) {
{
//code ommitted
}
// Reset parameters that may be overriddden bwlow
***void (Benchmark::*method)(ThreadState*) = NULL;*** // What does this code line mean? // Benchmark is a class.
bool fresh_db = false;
int num_threads = FLAGS_threads;
if (name == Slice("fillseq")) {
fresh_db = true;
method = &Benchmark::WriteSeq;
}
If required, I can give detailed implementation of Benchmark as well.
Thanks a lot for the help!
void (Benchmark::*method)(ThreadState*) = NULL;
// What does this code line mean?
// Benchmark is a class.
The above is a pointer to a member function. Since member functions are not like regular functions (they can only be called on a valid object), you cannot take their address it the same way you would for a free function.
Therefore the above syntax is introduced. It is similar to a regular function pointer except the class specifier Benchmark::. This is essentially the type of the implicit this pointer.
In your case, method is a pointer to a member function that takes ThreadState* as a parameter, and has a void return type. The reason for using it is most probably to simplify the call. First, and based on various parameters, a member function is chosen to be called, and its "address" stored in method. After all the checks are done, there is only a single call to the chosen function via the pointer to member.
Incidentally, &Benchmark::WriteSeq is how the code obtains the "address" of the member function WriteSeq. You must use the address-of operator on the qualified function name.
Actually I am new to writing handlers but somehow i managed to write this piece of code:
#include<iostream>
using namespace std;
class test
{
public:
typedef void (test::*MsgHandler)(int handle);
test()
{
cout<<"costructor called"<<endl;
}
void Initialize()
{
add_msg_Handler(4,&test::System);
}
void System(int handle)
{
cout<<endl<<"Inside System()"<<endl;
cout<<"handle:"<<handle<<endl;
}
protected:
MsgHandler message[20];
void add_msg_Handler(int idx,MsgHandler handler)
{
cout<<endl<<"Inside add_msg_Handler()"<<endl;
cout<<"handler:"<<handler<<endl;
message[idx]=handler;
cout<<"message:"<<message[idx]<<endl;
}
};
int main()
{
test obj;
obj.Initialize();
return 0;
}
This code is working fine, I get the output as:
costructor called
Inside add_msg_Handler()
handler:1
message:1
But there are several things beyond my scope. If I am right System() should have been called in this line:
add_msg_Handler(4,&test::System);
but this is not happening. I need help on rectifying this.
Second thing is, I am not able to understand why I am getting such output:
handler:1
I mean how does handler got initialized to 1.Can somebody help me in solving this??
&test::System is not a function call, it's a pointer to the member function test::System.
(A call would look like System(0) and wouldn't compile if you used it as the parameter in question.)
If you look at the definition of add_msg_handler:
cout<<endl<<"Inside add_msg_Handler()"<<endl;
cout<<"handler:"<<handler<<endl;
message[idx]=handler;
cout<<"message:"<<message[idx]<<endl;
there's not a single place that calls the function handler.
(A call would look like (this->*handler)(0) or (this->*message[idx])(0).)
So the function isn't called because there's nothing in your code that calls it.
The output is 1 because
handler is a pointer to a member function
there's no overload of << for pointers to member functions
there is an implicit conversion from pointer to member function to bool
there's an overload of << for bool
a non-null pointer is implicitly converted to true
true outputs as 1 by default.
I want to call the following function and pass it a function with a parameter. The purpose of that is that it should call the function with my specified parameter so I know what triggered the function (in that case a gpio pin on the Raspberry Pi).
int wiringPiISR( int pin, int edgeType, void (*function)( void ) );
Currently I have:
for ( int i = 0; i < myValues.size(); ++i )
{
int myValue = myValues[ i ];
wiringPiISR( myValue, INT_EDGE_RISING, &myCallback( myValue ) );
}
Though this is giving me the following error:
error: lvalue required as unary ‘&’ operand
Which I can't really understand as to my understanding, myValue is an lvalue or is it not?
Is it what I want do even possible? If so how?
The function wiringPiISR is from a library called wiringPi and I would like to avoid modifying it as much as possible.
You could combine the answers from imreal and Ryan Haining something like this.
std::function<void()> cbfunc;
void myCallback()
{
cbfunc();
}
void myWiringPiISR(int val, int mask, std::function<void()> callback)
{
cbfunc = callback;
wiringPiISR(val, mask, &myCallback);
}
... and then use it...
void myActualCallback(int v)
{
... do something...
}
myWiringPiISR(myValue, INT_EDGE_RISING, std::bind(myActualCallback, myValue));
No need to patch library, and you can use all the bind/function goodness. I'll leave you to find a way around the thread safety issues...
How does it work? Put simply 'std::bind' is binding together a function and it's parameters into a single std:function object which can then be 'called' from the myCallback function which acts as a shim around the callback that you pass. I'd given the callback function a confusing name before, but this edit has hopefully fixed that.
You can "vomit" the function. This doesn't require a user-defined mutable global variable and is thread-safe, unless you have a compiler that supports multiple threads but not per-thread exceptions which would be basically unusable.
myWiringPiISRWrapper(Value value, int edge, std::function<void()> func) {
try {
throw &func;
} catch(...) {
myWiringPiISR(value, edge, [] {
try {
throw;
} catch(std::function<void()>* func) {
(*func)();
}
});
}
}
It's disgusting and slow, but it's totally encapsulated which I think is a worthwhile upside. Note that this only works if the callback is never executed after the call to myWiringPiISR returns. In this case you can of course have a callback with whatever bound state you desire.
If myValue is something you can decide at compile time, you could set it statically and use an intermediate function to pass in.
void myCallbackHelper() {
static constexpr int myValue = 3;
myCallback(myValue);
}
wiringPiISR(myValue, INT_EDGE_RISING, &myCallbackHelper);
If you need to determine myValue at run time, you could still accomplish this, but not really thread-safely.
int& getMyValue() {
static int myValue;
return myValue;
}
void setMyValue(int i) {
getMyValue() = i;
}
void myCallbackHelper() {
myCallback(getMyValue());
}
Then set it and call
setMyValue(3);
wiringPiISR(myValue, INT_EDGE_RISING, &myCallbackHelper);
I looked up wiringPiISR and found that it is some sort of api call, so i am assuming you cannot change it.
Having said that, there is a reason most api-calls with a function-pointer-callback look sort of like this
void setCallback( void (*function)(void* data), void* userdata);
This allows people to cast their struct {blabla} data; to add some userdata, and when the function is called, it is passed along.
So basically, apart from hacking stuff with static variables, you can't pass any arguments.
You need to use std::function and std::bind.
Change your function signature to
int wiringPiISR (int pin, int edgeType, std::function<void()> func);
Inside you can call the callback simply using func()
And your call to:
int myValue = 3;
wiringPiISR(myValue, INT_EDGE_RISING, std::bind(myCallback, myValue));
What this does is create a std::function object (i.e. a callable) that wraps your function and keeps your desired value in its state.
This will only work on C++11 and newer.
If you have c++11, I suggest using std::function - it's quite a bit cleaner.
If not, your function signature is wrong. You want a callback with the type void(int) but your function takes a void()
Say that you define a callback function as such:
typedef std::function<void(float)> Callback;
And you have a function as such:
void ImAFunction(float a)
{
//Do something with a
}
Is there a way to be able to store a function without an argument then pass one to it at a later time?
Such as this:
//Define the Callback storage
Callback storage;
storage = std::bind(ImAFunction, this);
//Do some things
storage(5);
This wont work which I explain with some of my real code below.
I can get close to what I wan't if I bind the value in with the std::bind function. Such as:
//Change
//storage = std::bind(ImAFunction, this);
storage = std::bind(ImAFunction, this, 5.0); //5.0 is a float passed
This works but when I go to pass a value through the function the outcome is whatever I set it to before:
storage(100); //Output is still 5
I am basing the fact that I think this is possible on this article.
http://www.cprogramming.com/tutorial/function-pointers.html
It doesn't use the function or bind functions but it does pass pointer arguments and performs exactly what I need. The reason I don't just skip the bind function is because I am trying to store the function in a class (private) and I can't store it if it's a template because it's created with the class.
The error produced above comes from this code:
struct BindInfo {
Callback keyCallback;
int bindType;
bool isDown;
bool held;
std::string name;
};
template <class T1>
void bindEvent(int bindType, T1* keydownObj, void(T1::*keydownF)(float), std::string name)
{
BindInfo newKeyInfo = { std::bind(keydownF, keydownObj), bindType, false, false, name };
inputBindings.insert(std::pair<int, BindInfo>(BIND_NULL, newKeyInfo));
};
The error is:
No viable conversion from '__bind<void(Main::*&)(float), Main *&>' to 'Callback' (aka 'function<void (float)>'
Is this possible? Thanks in advance.
You can include a placeholder for an unbound argument:
std::bind(&Main::ImAFunction, this, std::placeholders::_1);
If you find that a bit of a mouthful, a lambda might be more readable:
[this](float a){ImAFunction(a);}
It sounds like what you're looking for is a function pointer. While I don't have a lot of experience using them in C++ I have used them in C so: Yes, it is possible. Perhaps something like this:
void (*IAmAFunctionPointer)(float) = &IAmAFunction;
The best way to think about that line is, that IAmAFunctionPointer is a pointer (hence the *), it returns a void, and takes a float. Then later:
float a = 5;
IAmAFunctionPointer(a);
You could even design it so that the callback function is passed into the method (I assume this is what you're looking for).
void DoStuffThenCallback(float a, void (*callback)(float))
{
//DoStuff
callback(a);
}
further reading: http://www.cprogramming.com/tutorial/function-pointers.html
Using C++.
pthread_t threads[STORAGE]; // 0-99
...
void run()
Error>>> int status = pthread_create(&threads[0], NULL, updateMessages, (void *) NULL);
if (status != 0)
{
printf("pthread_create returned error code %d\n", status);
exit(-1);
}
...
void ClientHandler::updateMessages(void *)
{
string reqUpdate = "91"; // Request for update
string recvMSG;
while (true)
{
sleep(5);
sending(sock,reqUpdate); // send
recvMSG = receiving(sock); // receive
QString output(recvMSG);
emit signal_chat(output, 0); // Print message to text box
}
}
...
Compile Error:
TCPClient.cpp:109: error: argument of type ‘void (ClientHandler::)(void*)’ does not match ‘void* (*)(void*)’
I can't figure out whats wrong.
Thanks in advance.
A pointer to a member function is different from a global function with the same signature since the member function needs an additional object on which it operates. Therefore pointers to these two types of functions are not compatible.
In this case this means that you cannot pass a member function pointer to pthread_create but only a pointer to a non-member (or static) function. A work around for this problem is to use the forth parameter of pthread_create to pass a pointer to a object to a global function which then calls the method of the passed object:
class ClientHandler {
public:
void updateMessages();
void run();
};
// Global function that will be the threads main function.
// It expects a pointer to a ClientHandler object.
extern "C"
void *CH_updateMessages(void *ch) {
// Call "real" main function
reinterpret_cast<ClientHandler*>(ch)->updateMessages();
return 0;
}
void ClientHandler::run() {
// Start thread and pass pointer to the current object
int status = pthread_create(&threads[0], NULL, CH_updateMessages, (void*)this);
...
}
It's nothing to do with threads, it's a normal C++ error, you're just passing an incompatible type of function pointer.
A function pointer is not the same as a member instance function pointer, even if their signature is the same; this is because there is an implicit reference to *this passed. You can't avoid this.
As pthread_create takes a free function, create a static function(is a free function) inside ClientHandler
static void Callback(void * this_pointer,int other_arg) {
ClientHandler* self = static_cast< ClientHandler*>(this_pointer);
self-> updateMessages(other_arg);
}
and call pthread_create as follows
pthread_create(&threads[0], NULL, &ClientHandler::Callback, (void *) pointer_to_ClientHandler,int other_arg);
That works because Callback is free function
YoLinux has a nice pthread tutorial that my help you in learning about threads.
As others have already said, the problem is that the signatures between the functions are different. Class member functions always have a "secret" extra parameter, the this pointer. So you can never pass a member function where a global function is expected. You can hack around this either with libraries such as Boost.Bind, or by making the function a static member of the class.
But the simplest, and most elegant solution is to use a different threading API.
Boost.Thread is a very nice threading library for C++ (pthreads is designed for C, and that's why it doesnt play well with C++ features such as class methods).
I'd recommend using that.
Your code could be rewritten as something like this:
class ClientHandler {
public:
ClientHandler(/* All the parameters you want to pass to the thread. Unlike pthreads you have complete type safety and can pass as many parameters to this constructor as you like */){...}
void operator()() // boost.thread calls operator() to run the thread, with no parameters. (Since all parameters were passed in the constructor and saved as member variables
{
string reqUpdate = "91"; // Request for update
string recvMSG;
while (true)
{
sleep(5);
sending(sock,reqUpdate); // send
recvMSG = receiving(sock); // receive
QString output(recvMSG);
emit signal_chat(output, 0); // Print message to text box
}
}
// whatever arguments you want to pass to the thread can be stored here as member variables
};
boost::threead_group gr; // can store all your threads here, rather than being limited to your fixed-size array
gr.create_thread(ClientHandler(/* construct a ClientHandler object with the parameters you like*/));
You're passing a member function instead of a global, normal, one.
Just define:
void updateMessages(void *) {
static ClientHandler c;
// use c..
}