Recover in Cilk

Cilk makes it possible to recover from exceptions using try-catch blocks. This can stop an exception from aborting the program and let it continue with execution instead.

An example of where this can be useful: a server wouldn’t want to crash if one of the client connections exhibits a critical error. Instead, the server would want to close that connection and continue serving other clients.

#include <cilk/cilk.h>
#include <iostream>
#include <stdexcept>

// This function throws an exception.
void mayThrow() {
    throw std::runtime_error("a problem");
}

int main() {
    try {
        // The try block attempts to call the function that may throw an exception
        cilk_spawn mayThrow();
        cilk_sync;
        
        // This code will not run if mayThrow() throws an exception
        std::cout << "After mayThrow()" << std::endl;
    } catch (const std::exception& e) {
        // If an exception is thrown, it will be caught here
        std::cout << "Caught exception. Error:\n" << e.what() << std::endl;
    }

    return 0;
}

In Cilk, we use try-catch blocks to handle exceptions. The try block contains the code that might throw an exception, and the catch block handles any exceptions that are thrown.

The mayThrow() function is called using cilk_spawn, which allows it to be potentially executed in parallel. The cilk_sync ensures that we wait for the spawned task to complete before proceeding.

If mayThrow() throws an exception, the execution of the try block stops at that point, and control is transferred to the catch block. The catch block then handles the exception, in this case by printing out the error message.

To compile and run this Cilk program:

$ cilk++ -std=c++11 recover.cpp -o recover
$ ./recover
Caught exception. Error:
a problem

This demonstrates how Cilk can handle exceptions and prevent them from crashing the entire program, allowing for more robust error handling in parallel programs.