Timers in C++

#include <iostream>
#include <chrono>
#include <thread>
#include <future>

int main() {
    // Timers represent a single event in the future. You
    // tell the timer how long you want to wait, and it
    // provides a mechanism that will be notified at that
    // time. This timer will wait 2 seconds.
    auto timer1 = std::async(std::launch::async, []() {
        std::this_thread::sleep_for(std::chrono::seconds(2));
        return "Timer 1 fired";
    });

    // The future.get() blocks until the timer fires and the result is ready.
    std::cout << timer1.get() << std::endl;

    // If you just wanted to wait, you could have used
    // std::this_thread::sleep_for. One reason a timer may be useful is
    // that you can cancel the timer before it fires.
    // Here's an example of that.
    auto timer2 = std::async(std::launch::async, []() {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        return "Timer 2 fired";
    });

    // We can check if the timer has already completed
    if (timer2.wait_for(std::chrono::milliseconds(1)) == std::future_status::timeout) {
        std::cout << "Timer 2 stopped" << std::endl;
    } else {
        std::cout << timer2.get() << std::endl;
    }

    // Give the timer2 enough time to fire, if it ever
    // was going to, to show it is in fact stopped.
    std::this_thread::sleep_for(std::chrono::seconds(2));

    return 0;
}

This C++ code demonstrates the use of timers and asynchronous operations, which are similar concepts to those in the original example. Here’s a breakdown of the translation:

  1. We use std::chrono for time-related operations and std::thread for sleep functionality.

  2. Instead of Go’s channels, we use std::future and std::async to create asynchronous operations that simulate timers.

  3. The first timer is created using std::async. It sleeps for 2 seconds and then returns a message.

  4. We use future.get() to wait for the first timer to complete, which is analogous to receiving from a channel in the original example.

  5. For the second timer, we demonstrate how to check if it has completed using future.wait_for(). This allows us to “stop” the timer by not waiting for its completion if it hasn’t finished within a very short time (1 millisecond in this case).

  6. Finally, we use std::this_thread::sleep_for to wait for 2 seconds, giving the second timer ample time to complete if it was going to.

To compile and run this program:

$ g++ -std=c++11 timers.cpp -o timers
$ ./timers
Timer 1 fired
Timer 2 stopped

The output shows that the first timer fires after about 2 seconds, while the second timer is “stopped” before it has a chance to fire.

This example demonstrates how to work with timed operations and asynchronous tasks in C++, which are concepts similar to timers in other languages.