std::async doesn't seem to spawn thread with std::launch::async - c++

I am writing a DCPU-16 emulator and I am calculating the real time clock speed of the CPU by launching a thread that calls the function getRealTimeCPUClock() in a separate thread. The problem is it seems that the future object's "valid" attribute is true even when it has not returned a value. As a result, when calling futureObj.get(), it then waits for getRealTimeCPUClock() to return.
With a launch policy of async (as opposed to deferred) isn't it supposed to launch the function into the background and then when it returns set the valid attribute to true?
Is this the wrong usage?
int getRealTimeCPUClock() {
int cyclesBeforeTimer = totalCycles;
sleep(1);
return totalCycles - cyclesBeforeTimer;
}
void startExecutionOfProgram(char *programFileName)
{
size_t lengthOfProgramInWords = loadProgramIntoRAM(programFileName);
auto futureRealTimeClockSpeed = std::async(std::launch::async, getRealTimeCPUClock);
while(programCounter < lengthOfProgramInWords) {
if(futureRealTimeClockSpeed.valid()) {
realTimeClockSpeed = futureRealTimeClockSpeed.get();
futureRealTimeClockSpeed = std::async(std::launch::async, getRealTimeCPUClock);
}
step();
}
}

valid() does not what you think it does (although the entry in cppreference suggests otherwise).
Here is what the Standard says about valid():
(§ 30.6.6/18)
bool valid() const noexcept;
Returns: true only if *this refers to a shared state.
The value returned by valid() will be true as long as long as the future object is associated with a valid shared state, which is generally the case after you launched it using std::async and before you retrieve the result (using get()). The future will also be invalidated when you use the share() method to create a shared_future. None of this is related to what you are trying to do, i.e. checking whether the result is available.
To determine whether the result of a future is ready, I suggest using the wait_for() function with a delay of 0:
if (futureRealTimeClockSpeed.wait_for(std::chrono::seconds(0))
== std::future_status::ready)
/*...*/

Related

What is the benefit of `await_ready` in C++ coroutine awaiters

In C++ coroutines, awaiters-types (i. e. argument-types of co_await and return types of initial_suspend/final_suspend) require the three methods await_ready(), await_suspend(std::coroutine_handle<...>) and await_resume(). I am aware of the order of invocation1 in case of suspension/resumption of a coroutine.
But it is unclear to me what is the rationale of demanding the distinct await_ready-method. When returning true invocation of await_suspend is prevented (and with it suspension altogether). However, the same effect is achievable by simply returning true from await_suspend.
In this blog article the author David Mazières says
await_ready is an optimization. If it returns true, then co_await does not suspend the function. Of course, you could achieve the same effect in await_suspend, by resuming (or not suspending) the current coroutine, but before calling await_suspend, the compiler must bundle all state into the heap object referenced by the coroutine handle, which is potentially expensive.
However, to me this does not seem to be a valid argument: The (possibly heap-)allocated coroutine state needs to be created before promise_type::get_return_object() is invoked which is always invoked, since the promies_type-instance is part of the coroutine state. Therefore the coroutine state referenced by the handle is created anyway, regardless of whether we will invoke await_suspend or not.
Back to the question putting my thougths into code: I do not see in which case the rewriting of
struct awaiter
{
bool await_ready() { /* <arbitrary-await-ready-body> */ }
void /*| bool*/ await_suspend(std::coroutine_handle<...>) { /* <arbitrary-await-suspend-body> */ }
<any> await_resume() { ... }
};
to
struct awaiter
{
bool await_ready() { return false; } // always false
bool await_suspend(std::coroutine_handle<...>)
{
if (await_ready_result()) // effectively moved await_ready into await_suspend
return false;
/* <arbitrary-await-suspend-body> */
return true;
}
<any> await_resume() { ... }
private:
bool await_ready_result() { /* <arbitrary-await-ready-body> */ }; // could just be "in-lined" into await_suspend
};
would not be applicable. In the latter case awaiter_ready is obsolete without giving away any flexibility2. So what is the use of distinct awaiter_ready at all?
One thing that came to my mind was that await_ready could be kept noexcept when await_suspend's implementation is arbitrarily complex, which might allow for some optimization but that seems overly specific to be the actual rationale.
1: See for example the pseudo code block in section The Awaiter Workflow of article https://www.modernescpp.com/index.php/a-generic-data-stream-with-coroutines-in-c-20
2: I neglect the case of await_suspend returning some std::coroutine_handle, mainly because I don't see the particular use of that either. After all you could simply just call some_handle.resume() as last statement instead of returning it and instead return void/true. Feel free to enlighten me about that one as well.

Ending a loop on time expiration

I have a long computation in a loop, which I need to end prematurely if allowed compute time expires (and return a partially computed result). I plan to do it via SIGALARM handler and a timer:
// Alarm handler will set it to true.
bool expired = false;
int compute ()
{
int result;
// Computation loop:
for (...) {
// Computation here.
if (expired)
break;
}
return result;
}
My question is: how to correctly define the expired variable (volatile bool or std::atomic<bool>, or std::sig_atomic_t, etc), how to set it true in the signal handler (just an assignment or atomic operation), and how to check its value in the compute function?
This is a single-threaded C++17 code...
If you aren't using multiple threads, you don't need an atomic operation. Just set the global variable expired = true in the signal handler.
EDIT: as #Frank demonstrated below, the compiler might optimize it out. You can avoid this by declaring expired as volatile bool expired = false;
Unless one iteration takes a considerable amount of time, I would suggest that you don't bother with signals and simply check the gettimeofday at each iteration.

C++20 coroutines using final_suspend for continuations

BACKGROUND
After being convinced that C++ stackless coroutines are pretty awesome. I have been implementing coroutines for my codebase, and realised an oddity in final_suspend.
CONTEXT
Let’s say you have the following final_suspend function:
final_awaitable final_suspend() noexcept
{
return {};
}
And, final_awaitable was implemented as follows:
struct final_awaitable
{
bool await_ready() const noexcept
{
return false;
}
default_handle_t await_suspend( promise_handle_t h ) const noexcept
{
return h.promise().continuation();
}
void await_resume() const noexcept {}
};
If continuation here was retrieved atomically from task queue and the task queue is potentially empty (which could occur any time between await_ready and await_suspend) then await_suspend must be able to return a blank continuation.
It is my understanding that when await_suspend returns a handle, the returned handle is immediately resumed (5.1 in N4775 draft). So, if there was no avaliable continuation here, any application crashes as resume is called on an invalid coroutine handle after receiving it from await_suspend.
The following is the execution order:
final_suspend Constructs final_awaitable.
final_awaitable::await_ready Returns false, triggering await_suspend.
final_awaitable::await_suspend Returns a continuation (or empty continuation).
continuation::resume This could be null if a retrieved from an empty work queue.
No check appears to be specified for a valid handle (as it is if await_suspend returns bool).
QUESTION
How are you suppose to add a worker queue to await_suspend without a lock in this case? Looking for a scalable solution.
Why doesn't the underlying coroutine implementation check for a valid handle.
A contrived example causing the crash is here.
SOLUTION IDEAS
Using a dummy task that is an infinite loop of co_yield. This is sort of wasted cycles and I would prefer not to have to do this, also I would need to create seperate handles to the dummy task for every thread of execution and that just seems silly.
Creating a specialisation of std::coroutine_handle where resume does nothing, returning an instance of that handle. I'd prefer not specialise the standard library. This also doesn't work because coroutine_handle<> doesn't have done() and resume() as virtual.
EDIT 1 16/03/2020 Call continuation() to atomically retrieve a continuation and store the result in the final_awaitable structure, await_ready world return true if there wasn't a continuation available. If there was a continuation available await_ready would return false, await_suspend would then be called and the continuation returned (immediately resuming it).
This doesn't work because the value returned by a task is stored in the coroutine frame and if the value is still needed then the coroutine frame must not be destroyed. In this case it is destroyed after await_resume is called on the final_awaitable.
This is only an issue if the task is the last in a chain of continuations.
EDIT 2 - 20/03/2020 Ignore the possibility of returning a usable co routine handle from await_suspend. Only resume continuation from top level co routine. This doesn't appear as efficient.
01/04/2020
I still haven't found a solution that doesn't have substantial disadvantages. I suppose the reason I'm caught up on this is because await_suspend appears to be designed to solve this exact problem (being able to return a corountine_handle). I just cannot figure out the pattern that was intended.
You can use std::noop_coroutine as a blank continuation.
What about: (Just a large comment in fact.)
struct final_awaitable
{
bool await_ready() const noexcept
{
return false;
}
bool await_suspend( promise_handle_t h ) const noexcept
{
auto continuation = h.promise().atomically_pop_a_continuation();
if (continuation)
continuation.handle().resume();
return true;//or whatever is meaningfull for your case.
}
void await_resume() const noexcept {}
};

How to give the user some assigned time to answer?

Something like a stopwatch, give the person who is using my program about 30 second to answer, if no answer is got the program to exit ?
Basically the response shouldn't take more than the time given, otherwise the program will exit.
I found the answer by Axalo interesting, however fatally flawed by unfortunate minutia of std::async and std::future. So I'm presenting an alternative that eschews std::async but otherwise follows Axalo's basic design.
When I run Axalo's answer on my platform (which is conforming in the pertinent details), if the client never answers, getInputWithin never returns or exits. The program just hangs. And if the client answers well within the timeout, getInputWithin returns with the correct answer, but doesn't do so until the timeout period has expired.
The reason for this problem is subtle. It is well described in Herb Sutter's excellent paper N3630. A ~std::future() can block if it was returned by std::async() and will block until the associated task is done. This feature was intentionally put into async/future, and in the eyes of some, makes future completely useless.
Axalo's r1 and r2 are such std::futures whose destructor is supposed to block until the associated task is done. And this is why this solution hangs if the client never answers.
Below is an alternative answer which is built from thread, mutex, and condition_variable. It is otherwise very similar to Axalo's answer, but does not suffer from (what some consider) the design flaws of std::async.
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <memory>
#include <mutex>
#include <stdexcept>
#include <string>
#include <thread>
#include <tuple>
std::string
getInputWithin(std::chrono::seconds timeout)
{
auto sp = std::make_shared<std::tuple<std::mutex, std::condition_variable,
std::string, bool>>();
std::thread([sp]() mutable
{
std::getline(std::cin, std::get<2>(*sp));
std::lock_guard<std::mutex> lk(std::get<0>(*sp));
std::get<3>(*sp) = true;
std::get<1>(*sp).notify_one();
sp.reset();
}).detach();
std::unique_lock<std::mutex> lk(std::get<0>(*sp));
if (!std::get<1>(*sp).wait_for(lk, timeout, [&]() {return std::get<3>(*sp);}))
throw std::runtime_error("time out");
return std::get<2>(*sp);
}
int main()
{
std::cout << "please answer within 10 seconds...\n";
std::string answer = getInputWithin(std::chrono::seconds(10));
std::cout << answer << '\n';
}
Notes:
The timing stays within the chrono type system always. Prefer the type std::chrono::seconds to a scalar with a suggestive name (int timeoutInSeconds vs std::chrono::seconds timeout).
We need to launch a std::thread to handle the read from std::cin, as Axalo demonstrated. However we are going to need a std::mutex and std::condition_variable for communication instead of using the convenience of std::future. Both the main thread and this auxiliary thread need to share ownership of these communication objects, and we don't know which will die first. If the client never responds, the auxiliary thread may live forever, creating an effective memory leak, which is another problem not solved herein. But at any rate, the easiest way to share ownership is to store the communication objects with a copied std::shared_ptr. Last one out turns out the lights.
Launch a std::thread that waits for std::cin and signals the main thread if it gets it. The signaling must be done with the mutex locked. Note that this thread can be (indeed must be) detached. The thread can not touch any memory that it does not own (because of the shared_ptr owning all referenced memory). If main exits while the auxiliary thread is running, the OS will bring the thread down gracefully with no UB.
The main thread then locks the mutex and does a wait_for on the condition_variable using the specified timeout, and a predicate that is checking for the bool in the tuple to turn to true. This wait_for will either return early with that bool set to true, or it will return with it set to false after timeout seconds. If they race (timeout and client answer at the same time) it is ok, either there will be a string there or not, and the bool in the tuple answers that question. While
the main thread is executing the wait_for, the mutex is unlocked so the auxiliary thread can use it.
If the main thread returns and the bool in the tuple has not been set to true, then an exception is thrown. If this exception is not caught, std::terminate() will be called. Otherwise, the string in the tuple will have the client's response.
This approach is susceptible to a client creating many responses to which it never answers, and thus effectively growing memory leaks held by shared_ptrs which never get destructed. Solving that problem is not something I know how to do in portable C++.
In C++14, a slight modification can be done with getInputWithin which reduces the error of choosing the wrong member of the tuple. Since our tuple is composed of all different types, we can index it by type instead of by position:
std::string
getInputWithin(std::chrono::seconds timeout)
{
auto sp = std::make_shared<std::tuple<std::mutex, std::condition_variable,
std::string, bool>>();
std::thread([sp]() mutable
{
std::getline(std::cin, std::get<std::string>(*sp)); // here
std::lock_guard<std::mutex> lk(std::get<std::mutex>(*sp)); // here
std::get<bool>(*sp) = true; // here
std::get<std::condition_variable>(*sp).notify_one(); // here
sp.reset();
}).detach();
std::unique_lock<std::mutex> lk(std::get<std::mutex>(*sp)); // here
if (!std::get<std::condition_variable>(*sp).wait_for(lk, timeout,
[&]() {return std::get<bool>(*sp);})) // here
throw std::runtime_error("time out");
return std::get<std::string>(*sp); // here
}
That is, the lines marked // here have been changed with std::get<type>(*sp) as opposed to std::get<index>(*sp).
Update
In a fit of paranoia inspired by the good comment from TemplateRex below, I've added a call to sp.reset() as the last thing the aux thread does. This forces the main thread to be the one to destruct the tuple, eliminating the possibility that the aux thread could stall before destructing its local copy of sp, and let main blow through the atexit chain, and then have the aux thread wake up and run the tuple destructor.
There may be other reasons that exist to make the call to sp.reset() unnecessary. But by adding this preventative medicine, we don't have to worry about it.
If you don't want to use exit and kill the process you could do it this way:
std::string getInputWithin(int timeoutInSeconds, bool *noInput = nullptr)
{
std::string answer;
bool exceeded = false;
bool gotInput = false;
auto r1 = std::async([&answer, &gotInput]()
{
std::getline(std::cin, answer);
gotInput = true;
});
auto r2 = std::async([&timeoutInSeconds, &exceeded]()
{
std::this_thread::sleep_for(std::chrono::seconds(timeoutInSeconds));
exceeded = true;
});
while(!gotInput && !exceeded)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
if(gotInput)
{
if(noInput != nullptr) *noInput = false;
return answer;
}
if(noInput != nullptr) *noInput = true;
return "";
}
int main()
{
std::cout << "please answer within 10 seconds...\n";
bool noInput;
std::string answer = getInputWithin(10, &noInput);
return 0;
}
The nice thing about this is that you can now handle the missing input by using a default value or simply give the user a second chance, etc...

Pattern for future conversion

currently we are using asynchronous values very heavily.
Assume that I have a function which does something like this:
int do_something(const boost::posix_time::time_duration& sleep_time)
{
BOOST_MESSAGE("Sleeping a bit");
boost::this_thread::sleep(sleep_time);
BOOST_MESSAGE("Finished taking a nap");
return 42;
}
At some point in code we create a task which creates a future to such an int value which will be set by a packaged_task - like this (worker_queue is a boost::asio::io_service in this example):
boost::unique_future<int> createAsynchronousValue(const boost::posix_time::seconds& sleep)
{
boost::shared_ptr< boost::packaged_task<int> > task(
new boost::packaged_task<int>(boost::bind(do_something, sleep)));
boost::unique_future<int> ret = task->get_future();
// Trigger execution
working_queue.post(boost::bind(&boost::packaged_task<int>::operator (), task));
return boost::move(ret);
}
At another point in code I want to wrap this function to return some higher level object which should also be a future. I need a conversion function which takes the first value and transforms it to another value (in our actual code we have some layering and doing asynchronous RPC which returns futures to responses - these responses should be converted to futures to real objects, PODs or even void future to be able to wait on it or catch exceptions). So this is the conversion function in this example:
float converter(boost::shared_future<int> value)
{
BOOST_MESSAGE("Converting value " << value.get());
return 1.0f * value.get();
}
Then I thought of creating a lazy future as described in the Boost docs to do this conversion only if wanted:
void invoke_lazy_task(boost::packaged_task<float>& task)
{
try
{
task();
}
catch(boost::task_already_started&)
{}
}
And then I have a function (might be a higher level API) to create a wrapped future:
boost::unique_future<float> createWrappedFuture(const boost::posix_time::seconds& sleep)
{
boost::shared_future<int> int_future(createAsynchronousValue(sleep));
BOOST_MESSAGE("Creating converter task");
boost::packaged_task<float> wrapper(boost::bind(converter, int_future));
BOOST_MESSAGE("Setting wait callback");
wrapper.set_wait_callback(invoke_lazy_task);
BOOST_MESSAGE("Creating future to converter task");
boost::unique_future<float> future = wrapper.get_future();
BOOST_MESSAGE("Returning the future");
return boost::move(future);
}
At the end I want to be able to use it like this:
{
boost::unique_future<float> future = createWrappedFuture(boost::posix_time::seconds(1));
BOOST_MESSAGE("Waiting for the future");
future.wait();
BOOST_CHECK_EQUAL(future.get(), 42.0f);
}
But here I end up getting an exception about a broken promise. The reason seems to be pretty clear for me because the packaged_task which does the conversion goes out of scope.
So my questing is: How do I deal with such situations. How can I prevent the task from being destroyed? Is there a pattern for this?
Bests,
Ronny
You need to manage the lifetime of task object properly.
The most correct way is to return boost::packaged_task<float> instead of boost::unique_future<float> from createWrappedFuture(). The caller will be responsible to get future object and to prolongate task lifetime until future value is ready.
Or you can place task object into some 'pending' queue (global or class member) the similar way you did in createAsynchronousValue. But in this case you will need to explcitly manage task lifetime and remove it from queue after completion. So don't think this solution has advantages against returning task object itself.