How do I create a packaged_task with parameters? - c++

Following this excellent tutorial for futures, promises and packaged tasks I got to the the point where I wanted to prepare my own task
#include <iostream>
#include <future>
using namespace std;
int ackermann(int m, int n) { // might take a while
if(m==0) return n+1;
if(n==0) return ackermann(m-1,1);
return ackermann(m-1, ackermann(m, n-1));
}
int main () {
packaged_task<int(int,int)> task1 { &ackermann, 3, 11 }; // <- error
auto f1 = task1.get_future();
thread th1 { move(task1) }; // call
cout << " ack(3,11):" << f1.get() << endl;
th1.join();
}
As far as I can decipher the gcc-4.7.0 error message it expects the arguments differently? But how? I try to shorten the error message:
error: no matching function for call to
'std::packaged_task<int(int, int)>::packaged_task(<brace-enclosed initializer list>)'
note: candidates are:
std::packaged_task<_Res(_ArgTypes ...)>::---<_Res(_ArgTypes ...)>&&) ---
note: candidate expects 1 argument, 3 provided
...
note: cannot convert 'ackermann'
(type 'int (*)(int, int)') to type 'std::allocator_arg_t'
Is my variant how I provide the parameters for ackermann wrong? Or is it the wrong template parameter? I do not give the parameters 3,11 to the creation of thread, right?
Update other unsuccessful variants:
packaged_task<int()> task1 ( []{return ackermann(3,11);} );
thread th1 { move(task1) };
packaged_task<int()> task1 ( bind(&ackermann,3,11) );
thread th1 { move(task1) };
packaged_task<int(int,int)> task1 ( &ackermann );
thread th1 { move(task1), 3,11 };
hmm... is it me, or is it the beta-gcc?

Firstly, if you declare std::packaged_task to take arguments, then you must pass them to operator(), not the constructor. In a single thread you can thus do:
std::packaged_task<int(int,int)> task(&ackermann);
auto f=task.get_future();
task(3,11);
std::cout<<f.get()<<std::endl;
To do the same with a thread, you must move the task into the thread, and pass the arguments too:
std::packaged_task<int(int,int)> task(&ackermann);
auto f=task.get_future();
std::thread t(std::move(task),3,11);
t.join();
std::cout<<f.get()<<std::endl;
Alternatively, you can bind the arguments directly before you construct the task, in which case the task itself now has a signature that takes no arguments:
std::packaged_task<int()> task(std::bind(&ackermann,3,11));
auto f=task.get_future();
task();
std::cout<<f.get()<<std::endl;
Again, you can do this and pass it to a thread:
std::packaged_task<int()> task(std::bind(&ackermann,3,11));
auto f=task.get_future();
std::thread t(std::move(task));
t.join();
std::cout<<f.get()<<std::endl;
All of these examples should work (and do, with both g++ 4.6 and MSVC2010 and my just::thread implementation of the thread library). If any do not then there is a bug in the compiler or library you are using. For example, the library shipped with g++ 4.6 cannot handle passing move-only objects such as a std::packaged_task to std::thread (and thus fails to handle the 2nd and 4th examples), since it uses std::bind as an implementation detail, and that implementation of std::bind incorrectly requires that the arguments are copyable.

Since you're starting the thread with no arguments, you expect the task to be started with no arguments, as if task1() were used. Hence the signature that you want to support is not int(int, int) but int(). In turn, this means that you must pass a functor that is compatible with this signature to the constructor of std::packaged_task<int()>. Try:
packaged_task<int()> task1 { std::bind(&ackermann, 3, 11) };
Another possibility is:
packaged_task<int(int,int)> task1 { &ackermann };
auto f1 = task1.get_future();
thread th1 { move(task1), 3, 11 };
because the constructor of std::thread can accept arguments. Here, the functor you pass to it will be used as if task1(3, 11) were used.

Related

How to process instances of classes in parallel in C++?

I have a variable number of instances of one class, normally 3. I would like to call the class functions in each iteration of an infinite loop. Currently it is working sequentially, meaning I call each member function after each other. I would like to parallelize that part. What do you recommend?
I tried to construct an std::vector<std::thread>. I could initialize the threads and call a function on them at initialization.
MyCustomClass my_class_instance();
std::thread one_thread(&MyCustomClass::init, &my_class_instance, "string");
threads_.push_back(std::move(one_thread));
But now I would like to get each thread of the vector threads and then to call the class member function. If it would be a std::vector of class instances I would just call: vector.at(index).class_function(). How do I do that for threads? Or is that not possible?
By the way, it is in C++.
Thanks
In c++11, speciy std::launch::async is one of your choice, if asynchronicity is essential for you.
There are two launch policy:
std::launch::async, means that the function must be run asynchronously, i.e, on a different thread.
std::launch::deferred, means that the function may run only when get or wait is called on the future return by std::async. When get or wait is invoked, the function will execute synchronously. The caller of the function will be blocks until the fucntion finish running. If get or wait
is not invoked, then the function will never run.
auto future1 = std::async(my_function); // run my_function using defautl launch policy
auto future2 = std::async(std::launch::async | std::launch::deferred) // run my_function either async or defered
Refered from the book "Effective Modern C++" by Scoot Meyers, item 36: Specify std::launch ::async if asynchronicity is essential.
If parallel computing is what you need, you may consider using OpenMP.
Reference: https://en.cppreference.com/w/cpp/thread/async
This code maybe help you.
class test_thread_instanse
{
public:
void operator()(int x)
{
std::cout << "test" <<x << std::endl;
}
};
int main()
{
std::thread t1(test_thread_instanse(), 1);
std::thread t2(test_thread_instanse(), 2);
std::thread t3(test_thread_instanse(), 3);
t1.join();
t2.join();
t3.join();
return(0);
}

Pass QTimer::singleShot to std::async using std::bind

The following code starts a non-blocking timer that will launch the function myFunc after one second:
MyClass.h:
std::future<void> timer_future_;
MyClass.cpp:
timer_future_ = std::async(
std::launch::async,
[this] { QTimer::singleShot(1000,
[this] {this->myFunc();}
);
}
);
I would like to replace the lambda functions with std::functions. I have successfully replaced the second lambda as follows:
timer_future_ = std::async(
std::launch::async,
[this] { QTimer::singleShot(1000,
std::bind(&MyClass::myFunc, this)
);
}
);
How can I now replace the first lambda with another std::bind() call?
Note that the function QTimer::singleShot is from the Qt libraries; its documentation is here. Its prototype is:
void QTimer::singleShot(int msec, Functor functor)
As per this question, the definition of the Functor type can be found in QObject.h. It says:
template <class FunctorT, class R, typename... Args> class Functor { /*...*/ }
After some research, I understand that the std::bind() that will replace the first lambda must take account of the following:
QTimer::singleShot is an overloaded function, so I must use a cast to disambiguate the call to it
QTimer::singleShot is a static member function, so the pointer to it must resemble a pointer to a non-member function
I have made several unsuccessful attempts, the last of which was:
timer_future_ = std::async(
std::launch::async,
std::bind( ( void(*) (int, Functor<const std::function<void(void)>,void>) )&QTimer::singleShot,
1000,
std::bind(&MyClass::myFunc, this)
)
);
For this code, the MSVC compiler returned the error message
error: C2059: syntax error: ')'
on the third line.
Why don’t I just use the lambdas which are already working? The answer is simply that trying to use std::bind() instead is teaching me more about the various features of the C++ language and how to use them.
EDIT: Code that implements Kuba Ober's answer:
QTimer::singleShot(1000, [this] {
timer_future_ = std::async(
std::launch::async,
std::bind(&MyClass::myFunc, this)
);
});
The timer requires an event loop, and std::async will invoke it in a worker thread that doesn't have a running event loop. I question why would you ever want to do it?
If you want to run something in a worker thread after a delay, run the timer in a thread that has an event loop, and fire off the async action from that timer.
Count opening and closing brackets and add a semicolon

passing multiple arguments to a threaded function from another class

Say I have a class:
class This
{
void that(int a, int b);
};
and in my main function I need to start 'that' in a thread, and pass it 2 arguments.
This is what I have:
void main()
{
This t;
t.that(1,2); //works unthreaded.
std::thread test(t.that(1,2)); // Does not compile. 'evaluates to a function taking 0 arguments'
std::thread test2(&This::that, std::ref(t), 1, 2); //runs, but crashes with a Debug error.
}
I have searched, but have only found how to pass arguments to a thread, and to run a function from another class in a thread, but not both!
What is the correct way to do this?
In order to run This in another thread you either have to make a copy or ensure that it is still valid as long as the other thread is running. Try one of these:
Reference
This t;
std::thread test([&]() {
t.that(1,2); // this is the t from the calling function
});
// this is important as t will be destroyed soon
test.join();
Copy
This t;
std::thread test([=]() {
t.that(1,2); // t is a copy of the calling function's t
});
// still important, but does not have to be in this function any more
test.join();
Dynamic allocation
auto t = std::make_shared<This>();
std::thread(test[=]() {
t->that(1,2); // t is shared with the calling function
});
// You still have to join eventually, but does not have to be in this function
test.join();
The object t is destroyed at the end of the main() function, but the thread runs for some time after that. It results in an undefined behavior. It is also generally a good idea to join to all threads before quitting the program. Just put this at the end:
test2.join();
This::that does not take a reference to a This as its first argument.
I think what you want to do is more like
auto t = std::make_shared<This>();
std::thread test2{ [t](int a, int b) { t->that(a, b); }, 1, 2 };

Associate packaged_task and thread in C++

all
I have a class:
class someClass
{
public:
vector<int> someOperation(int start, int end)
{
// do something...
}
}
and a main function:
int main()
{
someClass obj;
std::packaged_task<vector<int>(int, int)> task(&someClass::someOperation);
std::thread t1 = std::thread(std::move(task), &obj, 0, 200); // Error happens here
std::thread t2 = std::thread(std::move(task), &obj, 201, 400);
std::thread t3 = std::thread(std::move(task), &obj, 401, 600);
t1.join();
t2.join();
t3.join();
return 0;
}
I expect this code can create three threads that run same operation on different part of a piece of data. However, in the definition of thread t1, compiler pops following error:
error C2046: term does not evaluate to a function taking 3 arguments
May I know what am I wrong, and how can I do it right?
Many thanks in advance.
Long
The problem is that &someClass::someOperation cannot be used without an instance of someClass. You realise that because you do pass one such instance into the thread constructor, but forgot it in the packaged_task signature:
std::packaged_task<vector<int>(someClass*, int, int)> task(&someClass::someOperation);
Another issue is that you are trying to move task into three different places. That won't work: after it moves once, the task won't be valid anymore, and moving it into the other threads won't do what you expect. You need three different tasks.

Get return code from std::thread? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++: Simple return value from std::thread?
Is there anyway to get the return code from a std::thread? I have a function which returns a integer, and I want to be able to get the return code from the function when the thread is done executing.
No, that's not what std::thread is for.
Instead, use async to get a future:
#include <future>
int myfun(double, char, bool);
auto f = std::async(myfun, arg1, arg2, arg3); // f is a std::future<int>
// ...
int res = f.get();
You can use the wait_for member function of f (with zero timeout) to see if the result is ready.
As others have suggested, the facilities in <future> can be used for this. However I object to the answer
No, you can't do this with std::thread
Here is one way to do what you want with std::thread. It is by no means the only way:
#include <thread>
#include <iostream>
int func(int x)
{
return x+1;
}
int main()
{
int i;
std::thread t([&] {i = func(2);});
t.join();
std::cout << i << '\n';
}
This will portably output:
3
Kerrek SB is correct with his answer, but I suggested to add another example (which he suggested should be an answer, so here it is).
I discovered recently that at least in VC11, std::async will not release all the resources of the thread until the end of the application, making possible to get memory leak false positive (if you are monitoring them using, for example Visual Leak Detector).
Here I mean that in most basic applications it is not worth looking at the rest of this answer, but if like me you need to check memory leaks and can't afford to let false positive, like static data not released at the end of the main function. If it's your case, then this might help.
std::async is not guaranteed to run in a separate thread by default, it is only if you use std::launch::async as first parameter. Otherwise the implementation decide what to do, and that's why VC11 implementation will use the new Microsoft Concurrency Runtime task manager to manage the provided function as a task pushed in a task pool, which mean threads are maintained and managed in a transparent way. There are ways to explicitely terminate the task manager but that's too platform specific, making async a poor choice when you want exactly 1) be sure to launch a thread and 2) get a result later and 3) be sure the thread is fully released when you get the result.
The alternative that does exactly that is to use std::packaged_task and std::thread in combination with std::future. The way it is done is almost similar to using std::async, just a bit more verbose (which mean you can generalize it in a custom template function if you want).
#include <packaged_task>
#include <thread>
int myfun(double, char, bool);
std::packaged_task<int(double, char, bool)> task(myfun, arg1, arg2, arg3);
auto f = task.get_future(); // f is a std::future<int>
First we create a task, basically an object containing both the function and the std::promise that will be associated with the future. std::packaged_task works mostly like an augmented version of std::function:
Now we need to execute the thread explicitly:
std::thread thread(std::move(task));
thread.detach();
The move is necessary because std::packaged_task is not copyable. Detaching the thread is only necessary if you only want to synchronize using the future – otherwise you will need to join the thread explicitly. If you don't, when thread's destructor is called, it will just call std::terminate().
// ...
int res = f.get(); // Synchronization and retrieval.
Here's an example using packaged_task:
#include <future>
#include <iostream>
void task_waiter(std::future<int>&& f) {
std::future<int> ft = std::move(f);
int result = ft.get();
std::cout << result << '\n';
}
int the_task() {
return 17;
}
int main() {
std::packaged_task<int()> task(the_task);
std::thread thr(task_waiter, task.get_future());
task();
thr.join();
return 0;
}