Closing Channels in Racket

#lang racket

(require racket/channel)

; In this example we'll use a `jobs` channel to communicate work to be done 
; from the main thread to a worker thread. When we have no more jobs for
; the worker we'll close the `jobs` channel.

(define (main)
  (define jobs (make-channel 5))
  (define done (make-channel))

  ; Here's the worker thread. It repeatedly receives from `jobs` with 
  ; `(channel-try-get jobs)`. This function returns two values: the received 
  ; value and a boolean indicating whether the receive was successful.
  ; We use this to notify on `done` when we've worked all our jobs.
  (thread
   (lambda ()
     (let loop ()
       (define-values (job more) (channel-try-get jobs))
       (cond
         [more
          (printf "received job ~a\n" job)
          (loop)]
         [else
          (printf "received all jobs\n")
          (channel-put done #t)]))))

  ; This sends 3 jobs to the worker over the `jobs` channel, then closes it.
  (for ([j (in-range 1 4)])
    (channel-put jobs j)
    (printf "sent job ~a\n" j))
  (channel-close jobs)
  (printf "sent all jobs\n")

  ; We await the worker using the synchronization approach we saw earlier.
  (channel-get done)

  ; Reading from a closed channel succeeds immediately, returning #f.
  ; The optional second return value is #t if the value received was 
  ; delivered by a successful send operation to the channel, or #f if 
  ; the channel is closed and empty.
  (define-values (_ ok) (channel-try-get jobs))
  (printf "received more jobs: ~a\n" ok))

(main)

To run this program, save it as closing-channels.rkt and execute it using Racket:

$ racket closing-channels.rkt
sent job 1
received job 1
sent job 2
received job 2
sent job 3
received job 3
sent all jobs
received all jobs
received more jobs: #f

In this Racket version, we use the racket/channel module to work with channels, which are similar to Go’s channels. The make-channel function creates a new channel, and channel-put and channel-get are used to send and receive values respectively.

Instead of goroutines, Racket uses threads. The thread function starts a new thread with the given function.

The channel-try-get function is used to receive from a channel, returning two values: the received value and a boolean indicating whether the receive was successful. This is similar to the two-value form of channel receive in Go.

Closing a channel in Racket is done with channel-close. After a channel is closed, channel-try-get will return #f for both values.

The concept of closing channels in Racket is similar to Go, allowing us to signal that no more values will be sent on the channel.

查看推荐产品

Comments powered by Disqus