The following code prints the argument passed to the function foo
in every 5 second interval.
function foo(arg) {
console.log(arg);
}
setInterval(() => foo(5), 5000);
I found this answer: https://stackoverflow.com/a/43373364/13798537 that calls a function at periodic interval, but I couldn't figure out how to call a function at periodic interval that takes argument as shown in the javascript code.
Is there an equivalent to the javascript code in C ?
Thanks.
CodePudding user response:
You actually can get pretty close to the javascript syntax:
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <memory>
#include <atomic>
using cancel_token_t = std::atomic_bool;
template<typename Fnc>
void set_interval(Fnc fun, std::chrono::steady_clock::duration interval,
std::shared_ptr<cancel_token_t> cancel_token=nullptr)
{
std::thread([fun=std::move(fun), interval, tok=std::move(cancel_token)]()
{
while (!tok || !*tok) // Call until token becomes true (if it is set)
{
auto next = std::chrono::steady_clock::now() interval;
fun();
std::this_thread::sleep_until(next);
}
}).detach();
}
void foo(int n)
{
std::cout << "Hello from foo("<<n<<")!\n";
}
int main()
{
using namespace std::chrono_literals;
auto cancel = std::make_shared<cancel_token_t>(false);
int x = 2;
// Ordinary rules for lambda capture apply so be careful
// about lifetime if captured by reference.
set_interval([x]{foo(5 x);}, 1000ms, cancel);
//set_interval([x]{foo(5 x);}, 1000ms); // Without token, runs until main exits.
std::this_thread::sleep_for(3s);
*cancel=true;
}
I've modified the linked question and added a cancellation token which cooperatively cancels the thread when set to true
. There is of course some delay between *cancel=true
and the loop check.
I made the token optional, if not used, the thread will die when process exits after return from main. Although this is not guaranteed by C , it works on common platforms.
std::chrono
enforces correct usage of time units.
Feel free to ask if I should explain anything.