'What is the equivalent to JavaScript setInterval in C++?

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.



Solution 1:[1]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1