context-select like features in C++

Viewed 130

Imagine a situation where I'd like to call a function that does some amount of processing, but is time-bound. I could write a function in golang using context.Context and select. I'd imagine something as follows:

package main

import (
    "context"
    "fmt"
    "time"
)

func longRunning(ctx context.Context, msg string) {
    stop := make(chan bool)
    done := make(chan bool)

    go func() {
        for {
            fmt.Printf("long running calculation %v...", msg)
            select {
            case <-stop:
                fmt.Println("time to stop early!")
                return
            default:
            }
        }
        done <- true
    }()

    select {
    case <-done:
        return
    case <-ctx.Done():
        stop <- true
        return
    }
}

func main() {
    ctx := context.Background()
    ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
    defer cancel()

    longRunning(ctx, "wheeee")
}

Is there a pattern I can use to achieve similar results in C++? in the sample above select is able to listen on a channel in a non-blocking way. Is having a eventfd file descriptor of some kind and listening to events the way to do it?

Any suggestions or tips would be much appreciated.

1 Answers

Something along these lines, perhaps:

void longRunning(std::atomic<bool>& stop) {
  for (;;) {
    if (stop) return;
    // Do a bit of work
  }
}

int main() {
  std::atomic<bool> stop = false;
  auto future = std::async(std::launch::async, longRunning, std::ref(stop));
  future.wait_for(std::chrono::seconds(num_seconds));
  stop = true;
  future.get();  // wait for the task to finish or exit early.
}

Demo

Related