In Qt Creator, using C++ I have to call the same function from another class for many times. However this slows down the overall performance speed. So in order to do real-time operation, I thought of using multithreading. After some search I found Qt Concurrent might help so tried the following steps.
My target function is in this class:
Class myClass
{
public foo(std::vector<float> inputVec, std::string inputStr);
}
And in my main class, I do this:
std::vector<float> mvec;
// here put some values into mvec;
std::string mstring = "test";
myClass mcl;
QFuture<float> f1 = QtConcurrent::run(mcl.foo(mvec, mstring));
f1.waitForFinished();
However, this gives out error saying:
no matching function for call to 'run(float)'
'functor' cannot be used as a function
'float' is not a class, struct, or union type
...
I also tried to use std::thread like this:
std::thread t1 = std::thread(mcl.foo, mvec, mstring);
if(t1.joinable()) t1.join();
But this throws the following error:
invalid use of non-static member function
I've tried many example codes online but still confused. How can I make this code to run smoothly and thread safe? Thank you.
The following statement, executes the foo method and passes the result of it to the run function.
QtConcurrent::run(mcl.foo(mvec, mstring));
The correct form is:
QtConcurrent::run(&mcl, &myClass::foo, mvec, mstring);
Also note that calling f1.waitForFinished(); after that, actually blocks your thread until the foo method completes. So you won't gain any advantage of multithreading.
You have to pass the (member-)function itself (plus the object the member shall relate to), not the result of just calling it. Have a look at the documentation:
QtConcurrent::run() also accepts pointers to member functions. The
first argument must be either a const reference or a pointer to an
instance of the class. Passing by const reference is useful when
calling const member functions; passing by pointer is useful for
calling non-const member functions that modify the instance.
For example, calling QByteArray::split() (a const member function) in
a separate thread is done like this:
// call 'QList<QByteArray> QByteArray::split(char sep) const' in a
separate thread QByteArray bytearray = "hello world";
QFuture<QList<QByteArray> > future = QtConcurrent::run(bytearray, &QByteArray::split, ',');
...
QList<QByteArray> result = future.result();
Thus, your code should rather look like
myClass mcl;
QFuture<float> f1 = QtConcurrent::run(&mcl, &myClass::foo, mvec, mstring);
f1.waitForFinished();
Related
This question already has answers here:
Start thread with member function
(5 answers)
Closed 4 years ago.
I would like to spawn a thread or a future calling this function:
std::string myClass::myFunction() const noexcept
I first tried spawning them both like this:
thread t0(myFunction); auto f1 = async(myFunction);
I would then get this error:
no instance of constructor "std::thread::thread" matches the argument list. argument types are: (std::string () const)
I then read online that since it is const I would need to call it by reference but all methods online have not worked, I am unsure if the problem is because the function is const or not.
What I have tried:
thread t0(&myClass::myFunction); auto f1 = async(&myClass::myFunction);
and
thread t0(&myFunction); auto f1 = async(&myFunction);
After this I would have two new errors that I cannot find a solution to:
std::invoke: no matching overloaded function found.
and
Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'
I think this is due to my lack of understand on how threads and futures work but I am struggling to find literature that gives me any relation to this.
Basically I don't really understand what rule I am breaking, if there is a fundamental flaw in my approach any direction or tips would be nice. Thank you for your time.
std::string myClass::myFunction() const noexcept
This is not a function. This is a class method. There is a fundamental different between the two.
You cannot simply write
myFunction();
Somewhere in your code, other than in another method of the same class, which uses this to invoke a different method for the same instance of the class. Anywhere outside a method of the same class, myFunction(); won't compile, and your compilation error is the same exact reason. The first parameter to std::thread's constructor is a function, not a class method. It can be a class method, which I'll get to shortly. But your first error is confusion between the concept of a function and a class method, that you need to understand.
You could make myFunction() a static class function, which then works just like any, ordinary, function, and then feed it to std::thread as usual. Another option is to construct std::thread using a wrapper function that passes whichever class whose method you wish to invoke to the wrapper function, and the wrapper function uses it. The "whichever class" could be this:
void invoke_func(const myClass *ptr)
{
ptr->myFunction();
}
// ...
std::thread new_thread{ this };
Another, a more modern approach that can be used to invoke a class method is to pass an additional parameter, a pointer to an instance of the class whose method you wish to invoke:
std::thread new_thread{ &myClass::myFunction, this };
The myFunction() method does not take any parameters here as arguments, but when the first parameter to std::thread's constructor is a class method, and not a function, the first parameter is taken to be a pointer to an instance of the class whose method gets invoked, with the remaining parameters getting forwarded as usual.
But you will need to figure out, on your own, which class's instance you are trying to invoke, whether this, or some other instance of your class.
Although you can often write foo() inside a class to invoke this->foo(), as a shortcut, this is not the case when you're outright "naming" the member function, and that's what you're doing here as you are actually passing a member function pointer to std::thread.
It can work, you just need to supply the object pointer too:
std::thread t0(myFunction, this);
You could pass a pointer to a different myClass instead, if you liked!
So I have done some research, and have found you can create a boost::thread object and have it start with a non-static class function by using "this" and boost::bind etc. It really doesn't make much sense to me and all the examples I could find had the boost::thread object launched within the same class as the function it was starting with so this could be used. I however, am launching the thread in a different class so I'm afraid by using "this", I will be saying the "this" is from the class I am creating the thread from, rather than the one the function is in (I'm probably wrong, I need to learn more about this "this" guy). Here is an example of my source I am having the problem with.
ANNGUI.h
class ANNGUI
{
private:
boost::thread *GUIThread;
Main *GUIMain;
public:
// Creates the entire GUI and all sub-parts.
int CreateGUI();
}
ANNGUI.cpp
int ANNGUI::CreateGUI()
{
GUIMain = new Main();
GUIThread = new boost::thread(GUIMain->MainThreadFunc);
};
This isn't all the source, but I think my problem is in here somewhere, I know I have to deal with the "this" somehow, but I'm unsure how. I Could use a static function, but I didn't really want to make my variables static either.
Thanks.
Also, Is there any very good resource for using any boost libraries? Their web site documentation seems good, but over my head.
The this keyword is used with boost::bind when the function object you're creating is bound to a object member function. Member functions can't exist apart from instances, so when creating a functor object out of a member function with boost::bind, you need a pointer to an instance. That's exactly what the this keyword actually is. If you use the this keyword within a member function of a class, what you get is a pointer to the current instance of that class.
If you were to call bind from outside a class member function, you might say something like:
int main()
{
Foo f;
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f));
}
Here, we're using Foo::some_function as our thread function. But we can't use this because we're calling bind from main. But the same thing could be achieved using this if we called bind from within a member function of Foo, like so:
void Foo::func1()
{
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this));
}
If a member function is static, or is simply a regular (non-member) function, then you don't need an instance pointer at all. You would just do:
boost::thread* thr = new boost::thread(some_regular_function);
As others mentioned, when you want to call an object method in a new thread, you have to supply the address of that object. But you don't need to call boost::bind, you can use the overloaded boost::thread constructor like this:
GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain);
If the method is in the same class you use this to get the address of the current instance, e.g.:
t = new boost::thread(&myclass::compute, this);
If the method has parameters, you can specify them after the second argument, e.g.:
t = new boost::thread(&myclass::compute, this, p1, p2);
boost::bind is your friend (it can sometimes have a rough way of showing it though)!
use GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));
and then make your MainThreadFunc a regular member. That means that you can use the instance variables directly like you would normally do.
Something like this:
class GUIMain {
public:
GUIMain() : m_Member(42) {}
void MainThreadFunc() {
// use all members as you would normally do
std::cout << m_Member << std::endl;
}
private:
int m_Member;
};
In cases like this it is useful to think of non-static member functions as free functions that take the this as first parameter, for example in your case void MainThreadFunc(Main* this).
boost::thread accepts a nullary functor, so you have to pass it a nullary functor which contains a reference to the instance GUIMain and calls GUIMain->MainThreadFunc which, seen as I explained above, would be something like MainThreadFunc(GUIMain).
Boost (and now also C++ with TR1) provides helpers to create such functors, namely boost::bind (or alternatively boost::lambda::bind). The expression boost::bind(f, arg1, arg2, ...) means "return a nullary functor which calls f(arg1, arg2, ...)".
That said, you can use the following expression to create the thread:
GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain))
If your object is a functor, i.e. has an operator(), you can pass an instance of it to boost::thread. The operator() does not need to be static. For example:
#include <boost/thread.hpp>
struct th {
void operator()();
};
void th::operator()()
{
for (;;) {
// stuff
}
}
int main()
{
th t;
boost::thread my_thread( t ); // takes a copy of t !
my_thread.join(); // blocks
return 0;
}
I have been playing with the c++11 thread for a while, and have some questions. People say that when you call a class member function in thread, this function has to be static. But it seems that this is not true. For example, I found this:
class bar
{ public:
void foo() {std::out << "Hello" << std::endl};
}
int main()
{
std::thread t0(&bar::foo, bar());
t0.join();
}
The above code works fine. It seems that the member function do not have to be static in c++11 standard. I want to know if my understanding is true. Another question is that, if I simply modify "void foo()" with "static void foo()", I get an error:
error: no type named 'type' in 'class std::result_of<void (*(bar))()>'
I do not understand this, but it seems that this is because the way I call the thread is not correct. I am very confuse in calling a function in a thread. For example, I found another way to call the same member function in the above example as
int main()
{ bar A;
std::thread t0(&bar::foo, &A);
}
It works also! I don't know the difference between these two ways. It seems that in the first way the constructor of the class will be performed each time I call foo(), while the in the second one it will not. Is that true? Besides, when calling member function in another class member function, the 'this' has to be passed.
I search the internet, all I can find is examples, without explaining the meaning of the arguments. Can anyone tell me how should I set the arguments (especially the first three) in a std::thread?
std::thread t0(&bar::foo) works pretty fine with static foo method.
Also, when asking a question consider to provide working code but not your text what you actually wrote just now right in the text field of this site.
Short answer to your question: provide this parameter to non-static class methods or don't provide it if it is static class method.
But, if you don't understand even that you must know one thing:
each class method works with this object which means a constant pointer to current object. While binding your function (I guess exactly binding works inside std::thread) the first parameter must be the object which method you want to call. Otherwise it is meaningless: you are trying to do something with what object then? The this exists in each non-static method of the class, implicitly, by first parameter of the method.
I recommend you to read the definitive c++ stackoverflow book guide and list
So, my problem is this:
I have a class called NetworkInterface that is built using the RakNet networking library.
It holds a method that uses the while loop that RakNet uses to send and receive data.
Now, I made the NetworkInterface class a singleton because I want it to only exist once throughout my game I'm writing.
But, if I'd just call the method with the while loop it would stop my whole gqme so thqt's why I wanted it to run on a different thread so it doesn't interfere with the game mechanics.
Now, I used the std::thread object to start the method in NetworkInterface on a different thread but it throws the C3867 error which states that the method needs to be static or some sort (I found this on Google already) but I don't know how to fix this because I have variables that are used in that method that can't be static as well.
I hope this is clear. In short, how would I implement a non-static method from a class in a seperate thread of my program. Or is there a better way? (I don't want to use the Boost library if that pops up)
You need to provide an object for you to call a non-static member function, just as you can't call method() on its own. To provide that object, pass it to std::thread's constructor after the argument where you put the function.
struct Test {
void func(int x) {}
};
int main() {
Test x;
std::thread t(&Test::func, &x, 42);
t.join();
}
LIVE EXAMPLE
Notice that I've passed &x. This is because non-static class functions accepts a pointer to the object where it is being called from, and this pointer is the this pointer. The rest, which is 42, is the arguments that corresponds to the method's parameter declaration with 42 coinciding with int x in the example.
So I have done some research, and have found you can create a boost::thread object and have it start with a non-static class function by using "this" and boost::bind etc. It really doesn't make much sense to me and all the examples I could find had the boost::thread object launched within the same class as the function it was starting with so this could be used. I however, am launching the thread in a different class so I'm afraid by using "this", I will be saying the "this" is from the class I am creating the thread from, rather than the one the function is in (I'm probably wrong, I need to learn more about this "this" guy). Here is an example of my source I am having the problem with.
ANNGUI.h
class ANNGUI
{
private:
boost::thread *GUIThread;
Main *GUIMain;
public:
// Creates the entire GUI and all sub-parts.
int CreateGUI();
}
ANNGUI.cpp
int ANNGUI::CreateGUI()
{
GUIMain = new Main();
GUIThread = new boost::thread(GUIMain->MainThreadFunc);
};
This isn't all the source, but I think my problem is in here somewhere, I know I have to deal with the "this" somehow, but I'm unsure how. I Could use a static function, but I didn't really want to make my variables static either.
Thanks.
Also, Is there any very good resource for using any boost libraries? Their web site documentation seems good, but over my head.
The this keyword is used with boost::bind when the function object you're creating is bound to a object member function. Member functions can't exist apart from instances, so when creating a functor object out of a member function with boost::bind, you need a pointer to an instance. That's exactly what the this keyword actually is. If you use the this keyword within a member function of a class, what you get is a pointer to the current instance of that class.
If you were to call bind from outside a class member function, you might say something like:
int main()
{
Foo f;
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f));
}
Here, we're using Foo::some_function as our thread function. But we can't use this because we're calling bind from main. But the same thing could be achieved using this if we called bind from within a member function of Foo, like so:
void Foo::func1()
{
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this));
}
If a member function is static, or is simply a regular (non-member) function, then you don't need an instance pointer at all. You would just do:
boost::thread* thr = new boost::thread(some_regular_function);
As others mentioned, when you want to call an object method in a new thread, you have to supply the address of that object. But you don't need to call boost::bind, you can use the overloaded boost::thread constructor like this:
GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain);
If the method is in the same class you use this to get the address of the current instance, e.g.:
t = new boost::thread(&myclass::compute, this);
If the method has parameters, you can specify them after the second argument, e.g.:
t = new boost::thread(&myclass::compute, this, p1, p2);
boost::bind is your friend (it can sometimes have a rough way of showing it though)!
use GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));
and then make your MainThreadFunc a regular member. That means that you can use the instance variables directly like you would normally do.
Something like this:
class GUIMain {
public:
GUIMain() : m_Member(42) {}
void MainThreadFunc() {
// use all members as you would normally do
std::cout << m_Member << std::endl;
}
private:
int m_Member;
};
In cases like this it is useful to think of non-static member functions as free functions that take the this as first parameter, for example in your case void MainThreadFunc(Main* this).
boost::thread accepts a nullary functor, so you have to pass it a nullary functor which contains a reference to the instance GUIMain and calls GUIMain->MainThreadFunc which, seen as I explained above, would be something like MainThreadFunc(GUIMain).
Boost (and now also C++ with TR1) provides helpers to create such functors, namely boost::bind (or alternatively boost::lambda::bind). The expression boost::bind(f, arg1, arg2, ...) means "return a nullary functor which calls f(arg1, arg2, ...)".
That said, you can use the following expression to create the thread:
GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain))
If your object is a functor, i.e. has an operator(), you can pass an instance of it to boost::thread. The operator() does not need to be static. For example:
#include <boost/thread.hpp>
struct th {
void operator()();
};
void th::operator()()
{
for (;;) {
// stuff
}
}
int main()
{
th t;
boost::thread my_thread( t ); // takes a copy of t !
my_thread.join(); // blocks
return 0;
}