问题
How can i create a timer that after a certain duration, it does something? so far i have been trying to use the % operation. I made a timer at the start of the function and subtracted the current time (now()function) then i % the difference by 5 because i want 5 seconds to pass:
(at the start of the program i defined start as high_resolution_clock::now())
duration<double> dur = start-high_resolution_clock::now();
if(dur%5==0)
the error ive been getting is: no operator "==" matches these operands -- operand types are: std::chrono::duration> == int
回答1:
You are looking for something like:
#include <chrono>
int main() {
using namespace std::chrono_literals;
using std::chrono::high_resolution_clock;
auto start = high_resolution_clock::now();
bool condition = true;
while (condition) {
auto time_passed = high_resolution_clock::now() - start;
if( time_passed % 5s == 0s ) {
// do your thing every 5 seconds
}
// ...
}
}
Code version 1, Code version 2
Explanation
The modulo
The modulo operation for duration called with: duration % x
expects x
to be either of the two:
another duration, in which case chrono does the job for you in getting the common type of
duration
andx
, that would allow modulo.some arbitrary type, in which case the inner type of
duration
should be able to perform modulo withx
. Which is not the case forduration
that is based on<double>
.
To allow modulo on duration
that is based on <double>
there is a need to use duration_cast
or to use the first modulo option above, with another duration
.
The comparison
The modulo operation returns a duration
as can be seen in the reference. To compare it to an int
(i.e. 0) there is a need to turn it into an int
(since duration
and int
are not comparable) and this can be done with a call to count, e.g.:
if ( (time_passed % 5s).count() == 0 )
Alternatively we can compare it to an actual duration as we do above.
An important design note
Even though above code works and when we reach the exact modulo we will do the thing, the value the duration
is counting is not in seconds, so if we just missed the 5 seconds by 2 nanos we will miss the modulo check and would not do our thing, then we will wait for the next round and would most probably miss it again. Modulo is a very bad choice for trying to catch the time, as the time that we sample jumps. A better approach would be to calculate that there has been 5 seconds or more since we last did the thing as a trigger. Which can be achieved with this code:
int main() {
using namespace std::chrono_literals;
using std::chrono::high_resolution_clock;
auto start = high_resolution_clock::now();
auto last_time_we_did_the_thing = start;
bool condition = true;
while (condition) {
auto curr_time = high_resolution_clock::now();
auto time_since_last_do_the_thing
= curr_time - last_time_we_did_the_thing;
if( time_since_last_do_the_thing >= 5s ) {
// do your thing every 5 seconds
last_time_we_did_the_thing = curr_time;
}
// ...
}
}
Code ^
来源:https://stackoverflow.com/questions/60477360/chrono-timer-in-c-to-double