I need to run my function MyFunc() every 5 seconds using the parameters in the code (i.e. minimum code changes).
There are two parameters in the code: ts and std::chrono::system_clock::now()
How do I write a condition so that I can run my function?
auto ts = std::chrono::system_clock::now() std::chrono::seconds(1);
do {
// 1s timer
if ( ts <= std::chrono::system_clock::now()) {
// ... doing some work
// here I need to start MyFunc() every 5s
if (/* condition */) {
MyFunc();
}
ts = std::chrono::seconds(1);
}
} while (isWork);
CodePudding user response:
The way in my mind is to check whether the time passed is greater than 5 seconds. You could do something similar to this, where there is a separate variable to keep track of 5 seconds after the last time that the function was run:
auto ts = std::chrono::system_clock::now() std::chrono::seconds(1);
auto fiveseconds = std::chrono::system_clock::now() std::chrono::seconds(5);
do {
// 1s timer
if ( ts <= std::chrono::system_clock::now()) {
// ... doing some work
// here I need to start MyFunc() every 5s
if (fiveseconds <= std::chrono::system_clock::now()) {
MyFunc();
fiveseconds = std::chrono::system_clock::now() std::chrono::seconds(5);
}
ts = std::chrono::seconds(1);
}
} while (isWork);
Note that this may not run it exactly every five seconds, just about when it runs the once-a-second loop, and then checks if it has been over five seconds.
CodePudding user response:
This is how I would do it. I don't use sleep because that could delay shutdown a lot. Instead I use a condition variable to wait at most 5 seconds to check if a stop condition is triggered, but returns immediately if the stop condition is triggered. This make reaction to your stopping much more responsive.
By using std::async the main thread keeps free for other things if needed.
#include <future>
#include <chrono>
#include <thread>
#include <iostream>
using namespace std::chrono_literals; // so we cant type 5s to mean 5 seconds
int main()
{
bool keep_running{ true }; // a flag indicating if you want to keep processing
std::condition_variable signal; // a signal between two threads that (maybe) keep_running has changed value
std::mutex mtx; // a mutex to use with flag/signal. (mutexes are often needed when more then 1 thread is involved)
std::cout << "press return to stop\n";
// launch a lambda function in a thread
// pass the boolean keep running
auto future = std::async(std::launch::async, [&]
{
while (keep_running)
{
std::cout << "."; // show we are looping
// get a lock, this is needed for safe waiting on the signal
std::unique_lock<std::mutex> lock{ mtx };
// I tend to never use sleep, but use a condition variable to
// be able to respond faster
// wait_for waits for 5s OR until keep_runnning is false
signal.wait_for(lock, 51s, [&] { return !keep_running; });
}
});
auto c = getchar();
std::cout << "stopping\n";
// update keep_running and condition variable in a lock too
{
std::unique_lock<std::mutex> lock{ mtx };
keep_running = false;
signal.notify_one();
}
future.get(); // wait for thread to have stopped.
std::cout << "stopped\n";
return 0;
}