Select in Chapel

Chapel’s select statement allows you to wait on multiple channel operations. Combining tasks and channels with select is a powerful feature of Chapel.

use Time;

proc main() {
    // For our example we'll select across two channels.
    var c1 = new channel(string);
    var c2 = new channel(string);

    // Each channel will receive a value after some amount
    // of time, to simulate e.g. blocking operations
    // executing in concurrent tasks.
    begin {
        Time.sleep(1);
        c1.write("one");
    }
    begin {
        Time.sleep(2);
        c2.write("two");
    }

    // We'll use `select` to await both of these values
    // simultaneously, printing each one as it arrives.
    for i in 1..2 {
        select {
            when var msg1 = c1.read() {
                writeln("received ", msg1);
            }
            when var msg2 = c2.read() {
                writeln("received ", msg2);
            }
        }
    }
}

We receive the values "one" and then "two" as expected.

$ chpl select.chpl
$ ./select
received one
received two

Note that the total execution time is only ~2 seconds since both the 1 and 2 second sleep operations execute concurrently.

In this Chapel version:

  1. We use the Time module for sleep functionality.
  2. Channels are created using new channel(type).
  3. Instead of goroutines, Chapel uses begin statements to create concurrent tasks.
  4. The select statement in Chapel is similar to that in other languages, allowing us to wait on multiple channel operations.
  5. We use writeln instead of fmt.Println for output.

This example demonstrates how Chapel’s concurrency features can be used to handle multiple asynchronous operations efficiently.