Channel Synchronization in Cilk

In Cilk, we can use threads to synchronize execution across parallel tasks. Here’s an example of using a blocking receive to wait for a thread to finish. When waiting for multiple threads to finish, you may prefer to use a cilk_sync construct.

#include <cilk/cilk.h>
#include <stdio.h>
#include <unistd.h>

// This is the function we'll run in a separate thread. The
// `done` variable will be used to notify the main thread
// that this function's work is done.
void worker(int *done) {
    printf("working...");
    sleep(1);  // Simulate work
    printf("done\n");
    
    // Set the flag to notify that we're done.
    *done = 1;
}

int main() {
    int done = 0;
    
    // Start a worker thread
    cilk_spawn worker(&done);
    
    // Block until we receive a notification from the
    // worker that it's finished
    while (!done) {
        // Busy wait
    }
    
    return 0;
}

To compile and run this Cilk program:

$ clang -fcilkplus channel-synchronization.c -o channel-synchronization
$ ./channel-synchronization
working...done

In this Cilk version, we use a shared variable done to synchronize between the main thread and the worker thread. The cilk_spawn keyword is used to create a new thread that runs the worker function.

The main thread then enters a busy-wait loop, continuously checking the done flag until it’s set by the worker thread. This is analogous to the channel receive operation in the original example.

Note that this is a simplistic implementation for demonstration purposes. In practice, you might want to use more sophisticated synchronization mechanisms provided by Cilk or the C standard library, such as atomic operations or mutexes, especially for more complex scenarios.

If you removed the while (!done) loop from this program, the program would likely exit before the worker even finished its task, similar to the behavior described in the original example.

Cilk provides other synchronization mechanisms that might be more appropriate in different scenarios, such as cilk_sync which waits for all spawned tasks to complete.