Junk Drawer Logo Junk Drawer

For all those little papers scattered across your desk

I stand for the Constitution, for due process, and for community that takes care of each other.

A note about Racket's GC for threads

D. Ben Knoble on 10 Jun 2025 in Blog

Yes, Racket will collect as garbage a thread that is blocked on a channel that can have no writers (according to Matthew Flatt).

Matthew also suggested a nice refinement of my program below that demonstrates the effect. I’ll show his first:

#lang racket

;; store a weak reference to the thread, but make sure the channel has no
;; writers
(define t
  (make-weak-box
   (let ()
     (define c (make-channel))
     (thread (thunk (sync c))))))

;; The (sync (system-idle-evt)) will not return until the thread has run as far
;; as it can, at which point it's GC-able. (The system-idle-evt constructor
;; exists essentially only for this kind of test/example.)
(sync (system-idle-evt))
(collect-garbage)
(weak-box-value t) ;=> #f

My original version was:

#lang racket

;; store a weak reference to the thread, but make sure the channel has no
;; writers
(define t
  (make-weak-box
   (let ()
     (define c (make-channel))
     (thread (thunk (sync c))))))

;; wait for the GC to collect…
(let loop ()
  (match (weak-box-value t)
    [(? thread?)
     ;; …by forcing it (but not too aggressively)
     (collect-garbage)
     (loop)]
    [#f (displayln "thread was GC'd")]))

It reliably prints and exits within a second or 2 on my machine.


Tags:

Categories: Blog

Load Comments
Previous Next
Back to posts