Signals in Cilk

Here’s the translation of the Go code to Cilk, formatted in Markdown suitable for Hugo:

Our program demonstrates how to handle signals in Cilk. We’ll show how to gracefully handle signals like SIGTERM or SIGINT. Here’s the full source code:

#include <iostream>
#include <csignal>
#include <cilk/cilk.h>
#include <cilk/cilk_api.h>

volatile sig_atomic_t signal_received = 0;

void signal_handler(int signal) {
    signal_received = signal;
}

int main() {
    // Register signal handlers
    std::signal(SIGINT, signal_handler);
    std::signal(SIGTERM, signal_handler);

    // Create a cilk_spawn to handle the signal
    cilk_spawn [&] {
        while (!signal_received) {
            _Cilk_sync;
        }
        std::cout << std::endl;
        std::cout << "Signal received: " << signal_received << std::endl;
    };

    std::cout << "Awaiting signal" << std::endl;

    // Wait for the signal
    while (!signal_received) {
        _Cilk_sync;
    }

    std::cout << "Exiting" << std::endl;

    return 0;
}

In this Cilk program, we use the standard C++ signal handling mechanisms along with Cilk’s concurrency features. Here’s a breakdown of the code:

  1. We include necessary headers for I/O, signal handling, and Cilk.

  2. We define a volatile sig_atomic_t variable to safely store the received signal across thread boundaries.

  3. The signal_handler function is defined to handle incoming signals.

  4. In the main function, we register signal handlers for SIGINT and SIGTERM.

  5. We use cilk_spawn to create a separate task that waits for a signal. This is similar to the goroutine in the original Go code.

  6. The main thread prints “Awaiting signal” and then waits in a loop until a signal is received.

  7. When a signal is received, both the spawned task and the main thread will detect it, print the appropriate messages, and the program will exit.

To compile and run this program, you would typically use:

$ cilk++ -O3 signals.cpp -o signals
$ ./signals
Awaiting signal
^C
Signal received: 2
Exiting

When we run this program, it will block waiting for a signal. By typing ctrl-C (which the terminal shows as ^C), we can send a SIGINT signal, causing the program to print the signal number (2 for SIGINT) and then exit.

This example demonstrates how Cilk can be used alongside traditional C++ features to handle system signals in a concurrent manner.