Select in Racket
Our example demonstrates how to wait on multiple channel operations. Combining threads and channels with a select-like mechanism is a powerful feature in concurrent programming.
#lang racket
(require racket/async-channel)
(define (main)
; For our example we'll select across two channels.
(define c1 (make-async-channel))
(define c2 (make-async-channel))
; Each channel will receive a value after some amount
; of time, to simulate e.g. blocking RPC operations
; executing in concurrent threads.
(thread
(lambda ()
(sleep 1)
(async-channel-put c1 "one")))
(thread
(lambda ()
(sleep 2)
(async-channel-put c2 "two")))
; We'll use a loop with synchronization to await both of these values
; simultaneously, printing each one as it arrives.
(for ([i (in-range 2)])
(match (sync c1 c2)
["one" (printf "received ~a\n" "one")]
["two" (printf "received ~a\n" "two")])))
(main)To run the program, save it as select.rkt and use the racket command:
$ time racket select.rkt
received one
received two
real 0m2.253s
user 0m0.031s
sys 0m0.015sWe receive the values “one” and then “two” as expected.
Note that the total execution time is only ~2 seconds since both the 1 and 2 second sleeps execute concurrently.
In this Racket version:
- We use
async-channels instead of Go’s channels. - Instead of goroutines, we use Racket’s
threadfunction to create new threads. - The
selectstatement is replaced with asyncfunction that can wait on multiple channels. - We use a
forloop withmatchto handle the different channel cases, similar to Go’sselect.
This example demonstrates how Racket can handle concurrent operations and channel-like communication between threads, similar to Go’s select mechanism.
Comments powered by Disqus