Timeouts in Cilk
Timeouts are important for programs that connect to external resources or that otherwise need to bound execution time. Implementing timeouts in Cilk is possible using a combination of threads and timers.
#include <cilk/cilk.h>
#include <cilk/cilk_api.h>
#include <iostream>
#include <chrono>
#include <thread>
#include <future>
int main() {
// For our example, suppose we're executing an external
// call that returns its result after 2s. We'll use a
// std::future to represent this asynchronous operation.
auto c1 = std::async(std::launch::async, []() {
std::this_thread::sleep_for(std::chrono::seconds(2));
return std::string("result 1");
});
// Here's the implementation of a timeout.
// We'll use std::future_status::timeout to check if
// the operation completed within the allowed time.
if (c1.wait_for(std::chrono::seconds(1)) == std::future_status::ready) {
std::cout << c1.get() << std::endl;
} else {
std::cout << "timeout 1" << std::endl;
}
// If we allow a longer timeout of 3s, then the operation
// will succeed and we'll print the result.
auto c2 = std::async(std::launch::async, []() {
std::this_thread::sleep_for(std::chrono::seconds(2));
return std::string("result 2");
});
if (c2.wait_for(std::chrono::seconds(3)) == std::future_status::ready) {
std::cout << c2.get() << std::endl;
} else {
std::cout << "timeout 2" << std::endl;
}
return 0;
}
Running this program shows the first operation timing out and the second succeeding.
$ g++ -fcilkplus timeouts.cpp -o timeouts
$ ./timeouts
timeout 1
result 2
In this Cilk version, we use std::async
to create asynchronous tasks that simulate long-running operations. We then use std::future::wait_for
to implement the timeout mechanism. If the future is ready within the specified time, we retrieve and print the result. Otherwise, we print a timeout message.
Note that Cilk doesn’t have built-in channels like Go, so we’ve used C++ futures and promises to achieve similar functionality. The cilk_spawn
keyword, which is typically used for parallelism in Cilk, isn’t necessary here as we’re using C++’s standard library for asynchronous operations.
This approach provides a way to implement timeouts in Cilk, although it’s not as elegant as Go’s channel-based solution. The core concept of bounding execution time remains the same.