RScheme supports user-level threads portably, even on operating systems that don't have threads at all. RScheme multiplexes several user threads onto one OS-level process. These threads appear to be preemptive from the normal user's point of view. (For example, nonblocking I/O is used so that one thread reading from the network doesn't block the whole process; the reading thread actually issues a nonblocking read request and a thread switch activates a waiting thread.)
When threads support is compiled in, the REPL comes up by default running in a thread. In this case, the ,tl directive will list all the threads in the system with their state, total run time, and the kind of object they are blocked on, if any. For example:
top=>,tl 0 [main] RUN 46.2 ms 1 [finalize] BLOCK 27 us #[<mailbox> "finalize"] 2 [monitor] BLOCK 54 us #[<mailbox> "signal"]
Synchronous exceptions (e.g., taking the car of 3) still generate a break loop in the thread causing the exception (typically the REPL thread itself).
Note: Need to talk about the backstop handler
However, when running a threaded REPL, an asynchronous interrupt (as from ^-C) will suspend the current thread group and create a new "break" thread group for a new REPL:
top=>^-C ** 0: Interrupt received: (SIGINT . #[<time> Thu Jul 17 16:21:00 2003]) break=>,tl 0 [main] SUSP 50 ms 1 [finalize] BLOCK 27 us #[<mailbox> "finalize"] 2 [monitor] BLOCK 3.1 ms #[<mailbox> "signal"] 3 [break] RUN 1.68 ms
When the break loop ends (as by EOF, or ^-D), the suspended thread group is resumed.
In order to maintain thread progress, the low-level system call I/O and other blocking system calls should not normally be used (e.g., fd-read, fd-write, socket-accept, wait-for) since they will typically block the entire RScheme process waiting for the operation to complete.
The threads system uses select() internally to manage multiple outstanding non-blocking I/O requests. Therefore, when interacting with "slow" devices such as the network, use the appropriate procedures described in this chapter to create safe objects. See section the Section called Thread Safe Input and Output for more details.
Note: The procedures defined in this chapter are available from the rs.sys.threads.manager module.
The make-thread procedure is used to create threads. The system maintains a notion of thread groups, which is a hierarchy of thread sets. You can also determine what thread is currently running, and its thread group.