cyclone/examples/threading/producer-consumer.scm
2017-11-13 18:41:10 -05:00

54 lines
1.4 KiB
Scheme

;; An example program having multiple producers concurrently writing to a queue
;; and a single consumer reading from the queue.
(import
(scheme base)
(scheme read)
(scheme write)
(srfi 18))
;; Global queue and a lock to coordinate access to it.
;; Note ->heap is used to ensure any objects accessed by multiple threads are
;; not on a thread's local stack, since those objects can be moved at any time
;; by the thread's minor GC.
(define *queue* (->heap (list)))
(define *lock* (make-mutex))
(define (producer)
(let loop ((n 100))
(cond
((> n 0)
(mutex-lock! *lock*)
(display (cons 'a *queue*))
(newline)
(set! *queue* (->heap (cons (->heap n) *queue*)))
(mutex-unlock! *lock*)
(loop (- n 1)))
(else
(display "producer thread done")
(newline)))))
(define (consumer)
(let loop ()
;(display (list (null? *queue*) *queue*))
;(newline)
(define sleep? #f)
(mutex-lock! *lock*)
(cond
((not (null? *queue*))
(display (car *queue*))
(newline)
(set! *queue* (cdr *queue*)))
(else
(display "consumer sleeping")
(newline)
(set! sleep? #t)))
(mutex-unlock! *lock*)
(if sleep? (thread-sleep! 1))
(loop)))
(thread-start! (make-thread producer))
(thread-start! (make-thread producer))
(thread-start! (make-thread producer))
;(producer)
(consumer)
;(read)