# Help test via snapshots: parallel threads

**URL:** <https://racket.discourse.group/t/help-test-via-snapshots-parallel-threads/3920>\
**Category:** General\
**Created:** [August 25, 2025, 1:03pm UTC](https://racket.discourse.group/t/help-test-via-snapshots-parallel-threads/3920 "2025-08-25T13:03:48Z")\
**Posts on this page:** 1\
**Showing post:** 22

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [October 13, 2025, 12:09am UTC](https://racket.discourse.group/t/help-test-via-snapshots-parallel-threads/3920/22 "2025-10-13T00:09:44Z")

</div>

The `#:keep 'results` argument makes `thread` very similar to `delay/thread` (and, by extension, `delay/sync` or `delay/idle`). The big difference I see is that the promises catch exceptions and raise them when forces, whereas `thread` uses the exception handler, and a thread that ended in an exception will have `(void)` as its result, like a `#:keep #f` thread:

```scheme
> (list (thread-wait (thread #:keep 'results (lambda () (+ "oops")))))
+: contract violation
  expected: number?
  given: "oops"
 [,bt for context]
'(#<void>)

```

Maybe this makes sense: catching exceptions might be expensive, and maybe it's useful to have this as a lower-level mechanism. On the other hand, I'd guess catching exceptions is a relatively common desideratum, and maybe the implementation of `thread` is in a position to implement it especially efficiently, or just conveniently. Potentially a `#:keep result/exn` option could be added later.

It doesn't seem like there's a way to tell currently (without controlling the thread's thunk) if a thread terminated normally, with an exception, or by being killed.

Eventually, it would be nice to support parallelism for `delay/thread` and friends.

Finally, the existence of `delay/idle` led me to notice that the docs for `system-idle-evt` probably need an update for parallel threads:

> Returns an event that is [ready for synchronization](https://users.cs.utah.edu/plt/snapshots/current/doc/reference/sync.html#%28tech._ready._for._synchronization%29) when the system is otherwise idle: if the result event were replaced by [`never-evt`](https://users.cs.utah.edu/plt/snapshots/current/doc/reference/sync.html#%28def._%28%28quote._~23~25kernel%29._never-evt%29%29), no thread in the system would be available to run. In other words, all threads must be suspended or blocked on events with timeouts that have not yet expired.

From this experiment, it looks like parallel threads must also be blocked, but I'm not sure that behavior is desirable:

```scheme
> (define stop? #f)
> (define n 0)
> (thread #:pool 'own (lambda ()                                 
                        (let loop ()                           
                          (if stop?                           
                              (displayln n)      
                              (begin (set! n (add1 n))
                                     (loop))))))
#<thread>
> (list n (sync (system-idle-evt)) n (set! stop? #t) n)
^Cuser break [,bt for context]

```

On the other hand, syncing on `(system-idle-evt)` in a parallel thread seems to work fine:

```scheme
> (sync (thread #:pool 'own
                #:keep 'results
                (lambda ()
                  (sync (system-idle-evt))
                  1)))
#<thread>

```

---

_[View the full topic](https://racket.discourse.group/t/help-test-via-snapshots-parallel-threads/3920)._
