SBCL supports a system-wide event scheduler implemented on top of
setitimer that also works with threads but does not require a
separate scheduler thread.
The following example schedules a timer that writes “Hello, word” after two seconds.
(schedule-timer (make-timer (lambda () (write-line "Hello, world") (force-output))) 2)
It should be noted that writing timer functions requires special care, as the dynamic environment in which they run is unpredictable: dynamic variable bindings, locks held, etc, all depend on whatever code was running when the timer fired. The following example should serve as a cautionary tale:
(defvar *foo* nil) (defun show-foo () (format t "~&foo=~S~%" *foo*) (force-output t)) (defun demo () (schedule-timer (make-timer #'show-foo) 0.5) (schedule-timer (make-timer #'show-foo) 1.5) (let ((*foo* t)) (sleep 1.0)) (let ((*foo* :surprise!)) (sleep 2.0)))
Timer type. Do not rely on timers being structs as it may change in future versions.
Create a timer object that's when scheduled runs
threadis a thread then that thread is to be interrupted with
tthen a new thread is created each timer
functionis run. If
functioncan be run in any thread. When
interrupt-threadis used to run
functionand the ordering guarantees of
interrupt-threadalso apply here.
functionalways runs with interrupts disabled but