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.
func Background() Context. Background returns a non-nil, empty Context. It is never canceled, has no values, and has no deadline. It is typically used by the main function, initialization, and tests, and as the top-level Context for incoming requests.
context is a standard package of Golang that makes it easy to pass request-scoped values, cancelation signals, and deadlines across API boundaries to all the goroutines involved in handling a request.
It typically stands for "context". Usually this is some structure that gets passed around to functions in a library, used to maintain state (i.e., the context of the function call). It's a preferable alternative to using global variables.
Context , your functions will know the context is done because Go's web server will cancel it, and that they can skip running any other database queries they haven't already run. This will free up web server and database server processing time so it can be used on a different request instead.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With