Non Blocking Channel Operations in Racket
Our first example demonstrates non-blocking channel operations in Racket. While Racket doesn’t have built-in channels like Go, we can use its thread and channel system to achieve similar functionality.
#lang racket
(define (main)
(define messages (make-channel))
(define signals (make-channel))
; Here's a non-blocking receive. If a value is
; available on `messages` then it will be received.
; If not, it will immediately take the else case.
(match (sync/timeout 0 messages)
[(? string? msg) (printf "received message ~a\n" msg)]
[_ (printf "no message received\n")])
; A non-blocking send works similarly. Here `msg`
; cannot be sent to the `messages` channel, because
; the channel has no buffer and there is no receiver.
; Therefore the else case is selected.
(define msg "hi")
(match (sync/timeout 0 (channel-put-evt messages msg))
['ok (printf "sent message ~a\n" msg)]
[_ (printf "no message sent\n")])
; We can use multiple cases to implement a multi-way
; non-blocking select. Here we attempt non-blocking
; receives on both `messages` and `signals`.
(match (sync/timeout 0 messages signals)
[(? string? msg) (printf "received message ~a\n" msg)]
[(? boolean? sig) (printf "received signal ~a\n" sig)]
[_ (printf "no activity\n")]))
(main)
To run the program, save it as non-blocking-channel-operations.rkt
and use the racket
command:
$ racket non-blocking-channel-operations.rkt
no message received
no message sent
no activity
In this Racket version:
We use
make-channel
to create channels similar to Go’s unbuffered channels.The
sync/timeout
function is used to implement non-blocking operations. It attempts to synchronize on an event (like receiving from a channel) for a specified time (0 in this case, making it non-blocking).We use Racket’s pattern matching (
match
) to handle different cases, similar to Go’sselect
statement.The
channel-put-evt
function is used to create an event for sending on a channel, which can be used withsync/timeout
for non-blocking sends.
While the concepts are similar, Racket’s approach to concurrency and channels is more explicit and flexible than Go’s built-in features. This example demonstrates how to achieve similar non-blocking behavior in Racket’s concurrent programming model.