C++: Simple return value from std::thread?
See this video tutorial on C++11 futures.
Explicitly with threads and futures:
#include <thread>
#include <future>
void func(std::promise<int> && p) {
p.set_value(1);
}
std::promise<int> p;
auto f = p.get_future();
std::thread t(&func, std::move(p));
t.join();
int i = f.get();
Or with std::async
(higher-level wrapper for threads and futures):
#include <thread>
#include <future>
int func() { return 1; }
std::future<int> ret = std::async(&func);
int i = ret.get();
I can't comment whether it works on all platforms (it seems to work on Linux, but doesn't build for me on Mac OSX with GCC 4.6.1).
Can one retrieve the return value of a thread function in C++11?
You can follow this sample code to get the return value from a thread :-
int main()
{
auto future = std::async(func_1, 2);
//More code later
int number = future.get(); //Whole program waits for this
// Do something with number
return 0;
}
In short, .get() gets the return value, you can typecast and use it then.
How to get a return value from a thread?
For obtaining return values form functions that are meant to be run in background, you may want to consider std::future
instead of directly creating an std::thread
object. You can use the std::async()
function template to start an asynchronous task. It returns an std::future
object that will eventually contain the return value of the function passed:
auto res = std::async(fun);
// ... optionally do something else
std::cout << res.get() << '\n';
That is, you create an std::future<int>
by calling std::async(func)
. Then, when you need fun()
's return value, you simply call the get()
member function on the future. If the future isn't ready yet (i.e., if it doesn't have the result yet), then the thread will block until it is.
Why not directly use std::thread
The problem with std::thread
is that it doesn't provide a direct mechanism for transferring the return value of the callable passed at its construction. For example, suppose you want to start a new thread with std::thread
to calculate the sum of two integers with the following function:
int sum(int a, int b) { return a + b; }
What you would probably try is:
std::thread th_sum(sum, 1, 2);
// ... optionally do something else
th_sum.join();
// calculation is finished, but where is the result?
The thread represented by th_sum
does calculate the sum of 1 and 2. However, you don't get sum()
's return value, i.e., the result, from the associated std::thread
object.
Instead, what you could do to handle this deficiency is, for example, to create a wrapper function for sum()
that has an out parameter for the result instead of returning it:
void sum_outparam(int a, int b, int& res) { res = sum(a, b); }
Then, you can start a new thread for running this wrapper function and with help of std::ref()
you will obtain the result in res
:
int res;
std::thread th_sum(sum_outparam, 1, 2, std::ref(res));
// ... optionally do something else
th_sum.join();
// now, res contains the result
Return a value from a thread in C++11
Lauching a thread and terminating it require many hundreds of machine cycles. But that's only a beginning. Context switches between threads, that are bound to happen if the threads are doing anything useful, will repeatedly consume even more many hundreds of machine cycles. The execution context of all these threads will consume many a byte of memory, which in turn will mess up many a line of cache, thus hindering the CPU efforts for yet another great deal of many hundreds of machine cycles.
As a matter of fact, doing anything with multitasking is a great consumer of many hundreds of machine cycles. Multitasking only becomes profitable in terms of CPU power usage when you manage to get enough processors working on lumps of data that are conceptually independent (so parallel processing won't threaten their integrity) and big enough to show a net gain compared with a monoprocessor version.
In all other cases, multitasking is inherently inefficient in all domains but one: reactivity. A task can react very quickly and precisely to an external event, that ultimately comes from some external H/W component (be it the internal clock for timers or your WiFi/Ethernet controller for network traffic).
This ability to wait for external events without wasting CPU is what increases the overall CPU efficiency. And that's it.
In terms of other performance parameters (memory consumption, time wasted inside kernel calls, etc), launching a new thread is always a net loss.
In a nutshell, the art of multitasking programming boils down to:
- identifying the external I/O flows you will have to handle
- taking reactivity requirements into account (remembering that more reactive = less CPU/memory efficient 99% of the time)
- setting up handlers for the required events with a reasonable efficiency/ease of maintenance compromise.
Multiprocessor architectures are adding a new level of complexity, since any program can now be seen as a process having a number of external CPUs at hand, that could be used as additional power sources. But your problem does not seem to have anything to do with that.
A measure of multitasking efficiency will ultimately depend on the number of external events a given program is expected to cope with simultaneously and within a given set of reactivity limits.
At last I come to your particular question.
To react to external events, launching a task each time a new twig or bit of dead insect has to be moved around the anthill is a very coarse and inefficient approach.
You have many powerful synchronization tools at your disposal, that will allow you to react to a bunch of asynchronous events from within a single task context with (near) optimal efficiency at (virtually) no cost.
Typically, blocking waits on multiple inputs, like for instance the unix-flavoured select()
or Microsoft's WaitForMultipleEvents()
counterpart.
Using these will give you a performance boost incomparably greater than the few dozen CPU cycles you could squeeze out of this task-result-gathering-optimization project of yours.
So my answer is: don't bother with optimizing thread setup at all. It's a non-issue.
Your time would be better spent rethinking your architecture so that a handful of well thought out threads could replace the hordes of useless CPU and memory hogs your current design would spawn.
How would I return a value while running a function from a thread
You can't return a value from a function using std::thread
but you can change the structure of the std::thread
to get your value or use std::sync
which returns an std::future<T>
holding your value, as follows
#include <iostream>
#include <thread>
int func(int a)
{
int b = a * a;
return b;
}
int main()
{
int result;
std::thread t([&] { result = func(3); });
t.join();
std::cout << result;
return 0;
}
or
#include <iostream>
#include <future>
int main()
{
auto f = std::async(std::launch::async, func, 3);
std::cout << f.get();
return 0;
}
C++ Get the return value from a threaded function later
You're requesting the result immediately rather than doing something else and then getting the result when you need it. If you do this:
int main()
{
auto future = std::async(func_1, 2);
//More code later
int number = future.get(); //Whole program waits for this
// Do something with number
return 0;
}
Then you can do something else in the More code later
bit and then block when you need the result by calling get()
.
Alternatively you can poll to see if the value is available using either wait_for or wait_until and do something if the result is not ready.
Can I return std::thread
Yes, it's safe, as long as the function's return value is used to initialize or assign to another std::thread
object.
The only precondition for std::thread
's destructor is that joinable()
is false
:
[thread.thread.destr]
~thread();
Effects: Ifjoinable()
, callsterminate()
. Otherwise, has no effects.
To be joinable()
, the thread must have an ID not equal to a value-initialized ID:
[thread.thread.member]
bool joinable() const noexcept;
Returns:get_id()
!=id()
.
And std::thread
's move constructor and move-assignment operator specify that a moved-from thread will have an ID equal to a value-initalized ID, and therefore will not be joinable()
:
[thread.thread.constr]
thread(thread&& x) noexcept;
Postconditions:x.get_id() == id()
andget_id()
returns the value ofx.get_id()
prior to the start of construction.
[thread.thread.assign]
thread& operator=(thread&& x) noexcept;
...
Postconditions:x.get_id() == id()
andget_id()
returns the value ofx.get_id()
prior to the assignment.
...
Since getWindowThread
returns a function-local variable, its return value will be move-constructed from the returned object, and since winT
will be move-constructed from the value returned by getWindowThread
, your example is safe. The returned thread
object is no longer joinable
and can be destroyed.
However, if the returned value is not used to initialize or assign to another std::thread
object, its destructor will call std::terminate()
and crash your program. For this reason, I would recommend adding the [[nodiscard]]
attribute to your function to ensure your compiler at least issues a warning in this dangerous situation (if you have access to C++17 features, otherwise there are compiler-specific extensions to enable the same behavior):
[[nodiscard]] std::thread getWindowThread(std::function<void()> f) {
std::thread t(f);
return t;
}
Related Topics
Regex Replace with Callback in C++11
C++ Program Converts Fahrenheit to Celsius
Efficient 128-Bit Addition Using Carry Flag
Error When Compiling Some Simple C++ Code
Start Windows Service from Application Without Admin Right(C++)
How to Render an Opengl Frame in C++ Builder
How to Compare Multiple Strings Inside an If Statement
Sort Array by First Item in Subarray C++
How to Create a Static Library with G++
What Does Template <Unsigned Int N> Mean
How to Update an Existing Element of Std::Set
How to Correctly Interpose Malloc Allowing for Ld_Preload Chaining
Reading from Ifstream Won't Read Whitespace
C++ High Precision Time Measurement in Windows
Is Adding to a "Char *" Pointer Ub, When It Doesn't Actually Point to a Char Array