I have an asynchronous process running (using std::async) which I want to measure the execution time and kill it if its taking too long. This process also returns a value after its execution, I would like to assign some default value as the result if it takes too long to compute. Any help/suggestions would be much appreciated!
#include <thread>
#include <future>
int compute(int val)
{
int result;
// do large computations
return result;
}
void main()
{
auto compute_thread = std::async(compute, 100);
// TODO: wait for result only for x milliseconds else assign some default value
int result = compute_thread.get();
// resume sequential code.
int final = result * 2;
}
Here is how my idea looks like (see inline code comments):
// Performs computations and exits when computation takes
// longer than maxTime. If the execution is timed out
// function returns valueIfTooLong.
// If the computation complete the function returns 0.
static int compute(int maxTime /*ms*/, int valueIfTooLong)
{
auto start = std::chrono::steady_clock::now();
for (short i = 0; i < std::numeric_limits<short>::max(); ++i)
{
auto now = std::chrono::steady_clock::now();
if (std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count() > maxTime)
{
return valueIfTooLong;
}
}
return 0;
}
Usage of the function:
int main()
{
const auto valueIfTooLong = 111;
const auto waitingTime = 10; // ms.
auto compute_thread = std::async(std::launch::async, compute, waitingTime, valueIfTooLong);
// Wait for result only for waitingTime milliseconds else assign valueIfTooLong
int result = compute_thread.get();
if (result == valueIfTooLong)
{
std::cout << "The calculation was longer than "
<< waitingTime << "ms. and has been terminated" << '\n';
}
else
{
std::cout << "The calculation is done" << '\n';
}
return 0;
}
You can use
std::future<int> compute_thread;
void main()
{
auto timeToWait = std::chrono::system_clock::now() + std::chrono::minutes(1); // wait for a minute
compute_thread = std::async(compute, 100);
// TODO: wait for result only for x milliseconds else assign some default value
std::future_status status = compute_thread.wait_until(timeToWait);
if(status == std::future_status::ready)
int final = compute_thread.get() * 2;
else
// you need another value based on what you're doing
}
Note: if your async is a long computation you may have for example another function that calculates the same thing but less accurate...
In this case there's not a kill of the sync task. You only wait for the completion (if in time) and you kepp doing your job if the result is not ready... It's a way to not being blocked on a compute_thread.wait()
Note 2: std::future<int> compute_thread is declared as global, because if you do this in a function (not in main) you have to make sure that compute_thread's life is longer than the function life.
Related
I have the code sample bellow to measure the execution time of some piece of code:
int main()
{
auto before = chrono::steady_clock::now();
Sleep(30000);
auto after = chrono::steady_clock::now();
int duration = (std::chrono::duration_cast<std::chrono::seconds> ((after - before)).count());
cout << duration << endl;
return 0;
}
Normally it works fine and prints out 30 in the cout statement.
However, during testing I observed that if the computer were to go to sleep in between the auto before = ... statement and the auto after = ... statement (due to inactivity or whatever other reason), then the printed out time also counts the entire time the machine was asleep. This makes perfect sense since we are comparing a timepoint from before the machine going to sleep and one with after.
So my question is how can I make it so that the duration the machine was asleep is not counted in my final duration? Probably will need a ticker that doesn't increment while machine is asleep rather than timepoint measurements but I'm not aware of such a ticker.
This is a Windows specific question. As I understand, MacOS has mach_absolute_time which is exactly what I'm looking for in windows. I'm using MSVC 19.29.30147.0 as my compiler.
After looking around and testing it out, the solution is to use QueryUnbiasedInterruptTime
Running the following code snippet, I manually put my machine to sleep while the program was stuck on the sleep statement and I observed that the second print out consistently outputs 15 seconds regardless of how long I leave my machine in a sleeping state. However, the first print-out that uses GetTickCount64 will include the amount of time the machine was asleep.
int main()
{
ULONGLONG before_query, after_query= 0;
QueryUnbiasedInterruptTime(&before_query);
auto beforeticks = GetTickCount64();
Sleep(15000);
QueryUnbiasedInterruptTime(&after_query);
auto afterticks = GetTickCount64();
cout << "Ticks from gettickcount64 is " << (double (afterticks-beforeticks))/1000 << endl;
cout << "Unbiased time measure is " << double((after_query - before_query)/10000000) << endl;
return 0;
}
You are correct that the easiest way is to use a counter that is incremented each second. This is easily implemented with threads:
#include <thread>
#include <atomic>
#include <chrono>
using namespace std::literals::chrono_literals;
class ellapsed_counter {
std::atomic<bool> finished = false;
std::atomic<unsigned int> value = 0;
std::thread worker { [this] {
while(!finished) {
value++;
std::this_thread::sleep_for(1s);
}
} };
public:
void finish() noexcept {
finished = true;
if(worker.joinable()) worker.join();
}
unsigned int ellapsed() const noexcept { return value; }
};
This will keep incrementing on 1s intervals (probably with some error) as long as the process is running and should cease so when it is sleeping.
You can use it like this:
#include <iostream>
int main(int argc, const char *argv[]) {
ellapsed_counter counter;
unsigned int last = 0, count = 0;
while(count < 10) {
count = counter.ellapsed();
if(count != last) {
last = count;
std::cout << count << std::endl;
}
}
counter.finish();
return 0;
}
This will count from 1 to 10 seconds and exit.
Details:
In the program below, multiple threads (in this case only 2 for simplicity) listen out for the same value of 66 to be returned from the functions, following some logic in both functions that produces the result 66.
The threads use async, and the values of 66 are returned using futures. A while loop is used in an attempt to continually check the status of threads one and two to check if either of them have completed, in which case the fastest result from either of the threads is then fetched and used in some calculation.
Goal:
Out of the two threads, to detect which one of them is first to return the value of 66
As soon as a thread returns 66 (regardless of if the other thread has completed), the returned value is then made available in main() for some further simple arithmetic to be performed upon it
If a thread returns 66 and arithmetic is performed upon this value in main(), and then the other thread later on delivers 66 as well, this second returned value should not be used in any calculations
Please note: before deciding to post this question, the following resources have been consulted:
How to check if thread has finished work in C++11 and above?
Using Multithreading two threads return same value with different inputs?
C++ threads for background loading
Future returned by a function
Start multiple threads and wait only for one to finish to obtain results
Problems and Current Ouput:
Currently, the program always outputs that the first thread to finish is rf1, even if the code in function1 is substantially slower (e.g. a for loop with 1000 iterations in function1, and a for loop with 10 iterations in function1). This leads me to believe there is some sort of blocking behaviour somewhere that I may have introduced?
Program Attempt:
#include <future>
#include <iostream>
#include "unistd.h"
double function1() {
// Logic to retrieve _value
// ...
double _value = 66;
return _value;
}
double function2() {
// Logic to retrieve _value
// ...
double _value = 66;
return _value;
}
int main() {
double ret_value = 0;
auto rf1 = std::async(std::launch::async, function1);
auto status1 = rf1.wait_for(std::chrono::nanoseconds(1));
auto rf2 = std::async(std::launch::async, function2);
auto status2 = rf2.wait_for(std::chrono::nanoseconds(1));
while (true) {
if (status1 == std::future_status::ready) {
std::cout << "RF1 FINISHED FIRST" << std::endl;
// No longer need returned val from 2nd thread.
// Get result from 1st thread
ret_value = rf1.get();
break;
}
else if (status2 == std::future_status::ready) {
std::cout << "RF2 FINISHED FIRST" << std::endl;
// No longer need returned val from 1st thread.
// Get result from 2nd thread
ret_value = rf2.get();
break;
}
else if (status1 != std::future_status::ready) {
// RF1 not finished yet
status1 = rf1.wait_for(std::chrono::nanoseconds(1));
}
else if (status2 != std::future_status::ready) {
// RF2 not finished yet
status2 = rf2.wait_for(std::chrono::nanoseconds(1));
}
}
// Do some calculations on the quickest
// returned value
double some_value = ret_value + 40;
return 0;
}
Questions:
Q1. Can the program be modified in any way to detect the fastest thread to return so that the returned value of 66 can be used within main() for further calculations?
Q2. Has the while loop introduced any sort of blocking behaviour?
If anyone may be able to advise or point to some resources that could aid in solving this dilemma, it would be greatly appreciated. So far, it has been a challenge to find multithreading documentation that exactly matches this scenario.
EDIT:
Based on a helpful answer from #jxh, the else if conditions instructing the WHILE loop to continue waiting have been removed, as seen further below.
Furthermore, some logic has been added to function1 and function2 to see which one will finish first. As seen in the code, function1 has 98 iterations and function2 has 100 iterations, yet the output continually says that function2 has finished first:
#include <future>
#include <iostream>
#include "unistd.h"
double function1() {
// Logic to retrieve _value
for (int i = 0; i < 98; i++) {
std::cout << std::endl;
}
double _value = 66;
return _value;
}
double function2() {
// Logic to retrieve _value
for (int i = 0; i < 100; i++) {
std::cout << std::endl;
}
double _value = 66;
return _value;
}
int main() {
double ret_value = 0;
auto rf1 = std::async(std::launch::async, function1);
auto status1 = rf1.wait_for(std::chrono::nanoseconds(1));
auto rf2 = std::async(std::launch::async, function2);
auto status2 = rf2.wait_for(std::chrono::nanoseconds(1));
while (true) {
if (status1 == std::future_status::ready) {
std::cout << "RF1 FINISHED FIRST" << std::endl;
// No longer need returned val from 2nd thread.
// Get result from 1st thread
ret_value = rf1.get();
break;
}
else if (status2 == std::future_status::ready) {
std::cout << "RF2 FINISHED FIRST" << std::endl;
// No longer need returned val from 1st thread.
// Get result from 2nd thread
ret_value = rf2.get();
break;
}
status1 = rf1.wait_for(std::chrono::nanoseconds(1));
status2 = rf2.wait_for(std::chrono::nanoseconds(1));
}
// Do some calculations on the quickest
// returned value
double some_value = ret_value + 40;
return 0;
}
The logic in your code inside the while will always call rf1.wait_for() until its status is ready.
Since your ready checks will break out of the loop, you do not need to use else if to decide to do further waiting. Just do the two waits again, like you did before you entered the while.
status1 = rf1.wait_for(std::chrono::nanoseconds(1));
status2 = rf2.wait_for(std::chrono::nanoseconds(1));
You have updated your question and you changed the behavior of the called functions away from the original behavior. Instead of hashing over the changes, let's talk about the problem in general terms.
You are attempting to wait at a nanosecond resolution.
Your threads as currently implemented only differ by 2 iterations of a fairly trivial loop body.
The compiler is free to optimize the code in such a way that the functions could execute in nearly the same amount of time.
So, a 1 nanosecond peek back and forth on the futures is not a reliable way to determine which future was actually returned first.
To resolve a close finish, you could use a buzzer, like they do in game shows. The first to buzz is clearly indicated by a signal. Instead of trying to implement a real buzzer, we can mimic one with a pipe. And, the function buzzes in by writing a value to the pipe.
int photo_finish[2];
double function1() {
int id = 1;
//...
write(photo_finish[1], &id, sizeof(id));
double _value = 66;
return _value;
}
double function2() {
int id = 2;
//...
write(photo_finish[1], &id, sizeof(id));
double _value = 66;
return _value;
}
The waiting code then reads from the pipe, and observes the value. The value indicates which function completed first, and so the code then waits on the appropriate future to get the value.
pipe(photo_finish);
auto rf1 = std::async(std::launch::async, function1);
auto rf2 = std::async(std::launch::async, function2);
int id = 0;
read(photo_finish[0], &id, sizeof(id));
if (id == 1) {
auto status1 = rf1.wait();
//...
} else if (id == 2) {
auto status2 = rf2.wait();
//...
}
Note that the sample code omits error handling for brevity.
I am creating a C++ program that uses 100 random number generators. The number generators are split into two groups: ones that create 100 numbers and ones that create 10 000 000 numbers.
I am trying to see the difference between:
Using deferred launching for the 100 numbers and async for the 10 000 000 numbers.
Using only async for both types of number generators.
There's no difference in time, so my code has something wrong with it, but so far I haven't been able to find it because I am a beginner with C++.
Below is the code. I've commented the part that uses only async.
#include <iostream>
#include <chrono>
#include <future>
#include <list>
/*
Using both deferred and async launchings: 5119 ms
Using only async launching: 5139 ms
*/
using namespace std;
class RandomNumberGenerator
{
public:
enum class task { LIGHT, HEAVY };
task taskType;
RandomNumberGenerator(): taskType(task::LIGHT)
{
int rnd = rand() % 2;
if (rnd == 0)
{
taskType = task::LIGHT;
}
else
{
taskType = task::HEAVY;
}
}
bool generateNumbers()
{
int number;
if(taskType == task::LIGHT)
{
for (int i = 0; i < 100; i++)
{
number = rand();
}
}
else
{
for (int i = 0; i < 1000000; i++)
{
number = rand();
}
}
return true;
}
};
int main()
{
cout << "Starting to generate numbers\n";
RandomNumberGenerator objects[100];
auto start = chrono::system_clock::now();
for (int i = 0; i < 100; i++)
{
objects[i].generateNumbers();
future<bool> gotNumbers;
if (objects[i].taskType == RandomNumberGenerator::task::LIGHT)
{
gotNumbers = async(launch::deferred, &RandomNumberGenerator::generateNumbers, &objects[i]);
}
else
{
gotNumbers = async(launch::async, &RandomNumberGenerator::generateNumbers, &objects[i]);
}
bool result = gotNumbers.get();
//future<bool> gotNumbers = async(launch::async, &RandomNumberGenerator::generateNumbers, &objects[i]);
//bool result = gotNumbers.get();
}
auto end = chrono::system_clock::now();
cout << "Total time = " << chrono::duration_cast<chrono::milliseconds>(end - start).count() << " seconds\n";
}
using launch::deferred or launch::async the same amount of work still needs to be done the only difference is whether it is done on another thread and the current thread blocks waiting for that thread to finish when you call gotNumbers.get() or whether the result is calculated directly in the current thread when you call gotNumbers.get(). Either way you aren't gaining any performance by using additional threads as only one thread is ever executing at a time.
If you start executing the async work before calling objects[i].generateNumbers() you might see more difference (though the overhead of std::async might still outweigh the performance increase).
#if 1
future<bool> gotNumbers;
if ( objects[ i ].taskType == RandomNumberGenerator::task::LIGHT )
{
gotNumbers = async( launch::deferred, &RandomNumberGenerator::generateNumbers, &objects[ i ] );
}
else
{
gotNumbers = async( launch::async, &RandomNumberGenerator::generateNumbers, &objects[ i ] );
}
#else
future<bool> gotNumbers = async(launch::async, &RandomNumberGenerator::generateNumbers, &objects[i]);
#endif
objects[ i ].generateNumbers();
bool result = gotNumbers.get();
I'm having this problem, where I have a main loop, that needs to trigger an async work and must not wait for it to finish. What I want it to do is to check every while-loop whether the async work is done.
This can be accomplished with the future.wait_for().
Since I don't want to block the main loop, I can use future.wait_for(0).
So far so good.
In addition, I'd like to verify that I received (or didn't receive) an answer within X ms.
I can do that by checking how long since I launched the "async", and verify what comes first - X ms passed or future_status::ready returned.
My question - is this a good practice, or is there a better way to do it?
Some more information:
Since the main loop must launch many different async jobs, it means I need to have a lot of duplicated code - every launch needs to "remember" the timestamp it was launched and every time I check if the async job is ready, I need to re-calculate the time differences for each async job. This might be quite a hassle.
for now - this is an example of what I described (might have build errors):
#define MAX_TIMEOUT_MS 30
bool myFunc()
{
bool result = false;
//do something for quite some time
return result;
}
int main()
{
int timeout_ms = MAX_TIMEOUT_MS;
steady_clock::time_point start;
bool async_return = false;
std::future_status status = std::future_status::ready;
int delta_ms = 0;
while(true) {
// On first time, or once we have an answer, launch async again
if (status == std::future_status::ready) {
std::future<bool> fut = std::async (std::launch::async, myFunc);
start = steady_clock::now(); // record the start timestamp whenever we launch async()
}
// do something...
status = fut.wait_for(std::chrono::seconds(0));
// check how long since we launched async
delta_ms = chrono::duration_cast<chrono::milliseconds>(steady_clock::now() - start).count();
if (status != std::future_status::ready && delta_ms > timeout_ms ) {
break;
} else {
async_return = fut.get();
// and we do something with the result
}
}
return 0;
}
One thing you might want to consider: If your while loop doesn't do any relevant work, and just checks for task completion, you may be doing a busy-wait (https://en.wikipedia.org/wiki/Busy_waiting).
This means you are wasting a lot of CPU time doing useless work. This may sound counter-intuitive, but it can negatively affect your performance in evaluating task completion even if you are constantly checking it!
This can happen because this thread will look like it is doing a lot of work to the OS, and will receive high priority for processing. Which may make other threads (that are doing your async job) look less important and took longer to complete. Of course, this is not set in stone and anything can happen, but still, it is a waste of CPU if you are not doing any other work in that loop.
wait_for(0) is not the best option since it effectively breaks the execution of this thread, even if the work is not ready yet. And it may take longer than you expect for it to resume work (https://en.cppreference.com/w/cpp/thread/future/wait_for). std::future doesn't seem to have a truly non-blocking API yet (C++ async programming, how to not wait for future?), but you can use other resources such as a mutex and the try_lock (http://www.cplusplus.com/reference/mutex/try_lock/).
That said, if your loop still does important work, this flow is ok to use. But you might want to have a queue of completed jobs to check, instead of a single future. This queue would only be consumed by your main thread and can be implemented with a non-blocking thread-safe "try_get" call to get next completed jobs. As others commented, you may want to wrap your time-saving logic in a job dispatcher class or similar.
Maybe something like this (pseudo code!):
struct WorkInfo {
time_type begin_at; // initialized on job dispatch
time_type finished_at;
// more info
};
thread_safe_vector<WorkInfo> finished_work;
void timed_worker_job() {
info.begin_at = current_time();
do_real_job_work();
WorkInfo info;
info.finished_at = current_time();
finished_work.push(some_data);
}
void main() {
...
while (app_loop)
{
dispatch_some_jobs();
WorkInfo workTemp;
while (finished_work.try_get(&work)) // returns true if returned work
{
handle_finished_job(workTemp);
}
}
...
}
And if you are not familiar, I also suggest you to read about Thread-Pools (https://en.wikipedia.org/wiki/Thread_pool) and Producer-Consumer (https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem).
The code below runs tasks async and checks later if they are finished.
I've added some fake work and waits to see the results.
#define MAX_TIMEOUT_MS 30
struct fun_t {
size_t _count;
bool finished;
bool result;
fun_t () : _count (9999), finished (false), result (false) {
}
fun_t (size_t c) : _count (c), finished (false), result (false) {
}
fun_t (const fun_t & f) : _count (f._count), finished (f.finished), result (f.result) {
}
fun_t (fun_t && f) : _count (f._count), finished (f.finished), result (f.result) {
}
~fun_t () {
}
const fun_t & operator= (fun_t && f) {
_count = f._count;
finished = f.finished;
result = f.result;
return *this;
}
void run ()
{
for (int i = 0; i < 50; ++i) {
cout << _count << " " << i << endl;;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
result = true;
finished = true;
cout << " results: " << finished << ", " << result << endl;
}
operator bool () { return result; }
};
int main()
{
int timeout_ms = MAX_TIMEOUT_MS;
chrono::steady_clock::time_point start;
bool async_return = false;
std::future_status status = std::future_status::ready;
int delta_ms = 0;
std::map<size_t, fun_t> futs;
std::vector<std::future<void>> futfuncs;
size_t count = 0;
bool loop = true;
cout << "Begin --------------- " << endl;
while (loop) {
loop = false;
// On first time, or once we have an answer, launch async again
if (count < 3 && status == std::future_status::ready) {
//std::future<bool> fut = std::async (std::launch::async, myFunc);
futs[count] = std::move(fun_t(count));
//futs[futs.size() - 1].fut = std::async (std::launch::async, futs[futs.size() - 1]);
futfuncs.push_back (std::move(std::async(std::launch::async, &fun_t::run, &futs[count])));
}
// do something...
std::this_thread::sleep_for(std::chrono::seconds(2));
for (auto & f : futs) {
if (! f.second.finished) {
cout << " Not finished " << f.second._count << ", " << f.second.finished << endl;
loop = true;
} else {
bool aret = f.second;
cout << "Result: " << f.second._count << ", " << aret << endl;;
}
}
++count;
}
for (auto & f : futs) {
cout << " Verify " << f.second._count << ", " << f.second.finished;
if (f.second.finished) {
bool aret = f.second;
cout << "; result: " << aret;
}
cout << endl;
}
cout << "End --------------- " << endl;
return 0;
}
After removing lines (there are too much) you see the tasks. First number is the task id, second the iteration number.
Begin ---------------
0 0
0 1
0 2
Not finished 0, 0
1 0
0 20
1 1
Not finished 0, 0
Not finished 1, 0
2 0
1 20
0 40
2 1
0 49 // here task 0 ends
2 10
1 30
results: 1, 1 // "run" function ends
1 39
Result: 0, 1 // this is the verification "for"
Not finished 1, 0
Not finished 2, 0
results: 1, 1
Result: 0, 1
Result: 1, 1
Result: 2, 1
Verify 0, 1; result: 1
Verify 1, 1; result: 1
Verify 2, 1; result: 1
End ---------------
EDIT: Works just fine, I messed up in another place of my code.
I am trying to increase an Integer once every minute, using C++11 chrono library. For some reasons, the comparison does not work as it should: It just returns true every time. Is something wrong with the cast to seconds? Shouldn't the result be an int, containing the difference of both time points in seconds?
Would really appreciate your help! Here's the Code:
std::chrono::time_point<std::chrono::system_clock> starttime = std::chrono::system_clock::now();
int timeLine = 0;
int main() {
while (true) {
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
int seconds = timeLine * 60;
if ((std::chrono::duration_cast<std::chrono::seconds>(starttime - now)).count() + seconds <= 0) {
timeLine++;
nextConstellation();
cout << "Timeline: " << timeLine << endl;
}
}
}
Here is a safer, and more readable way to write this code:
std::chrono::time_point<std::chrono::system_clock> starttime = std::chrono::system_clock::now();
int timeLine = 0;
int main() {
while (true) {
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
std::chrono::seconds seconds = timeLine * std::chrono::minutes{1};
if (starttime - now + seconds <= std::chrono::seconds{0}) {
timeLine++;
nextConstellation();
std::cout << "Timeline: " << timeLine << std::endl;
}
}
}
In a nutshell, stay within the chrono-type system, and trust it to do the units conversions for you, implicitly wherever possible.
Or perhaps even more simply:
// ...
auto timelimit = timeLine * std::chrono::minutes{1};
if (now - starttime >= timelimit) {
// ...
And if in C++14, add using namespace std::chrono_literals and:
auto timelimit = timeLine * 1min;