I agree, it is a simple concept, and easily implementable using condition variables. However, it would probably be nicer if guile provided some standard solution, instead of forcing every programmer to coming up with their own ones.
I've noticed that there's a module (ice-9 occam-channel) bundled with Guile, but unfortunately it is undocumented. Maybe it is a problem with the Guile community that -- despite some attempts like Guildhall -- we didn't manage to create anything like CPAN or pip. (I think that the Chicken community was more successful in that regard) 2016-09-10 16:30 GMT+02:00 Chris Vine <ch...@cvine.freeserve.co.uk>: > On Sat, 10 Sep 2016 11:37:55 +0200 > Panicz Maciej Godek <godek.mac...@gmail.com> wrote: > > Hi, > > is there any easy way to create a channel (queue) that could be used > > to communicate between threads? In particular, if the queue is empty, > > I would like the consumer to wait until something appears in it > > (pretty much like the channels in Clojure) > > I haven't used Clojure channels, but what you describe is a traditional > blocking asynchronous queue. Since guile has POSIX condition variables > they are trivial to make. Here is one simple implementation, which > allows multiple writers and multiple readers. async-queue-pop! blocks a > reader until something is available in the queue. If there are > multiple readers, which reader awakens on any write is for the thread > scheduler. A loop is included in async-queue-pop! because POSIX > condition variables can spuriously wake up, so you have to test the > condition (whether the queue is empty or not) on any wake up before > returning. > > You will find loads of literature and tutorials on this pattern, using > condition variables. > > > ****************************************** > > (use-modules (srfi srfi-9) > (ice-9 q) > (ice-9 threads)) > > (define-record-type <async-queue> > (_make-async-queue mutex cond q) > async-queue? > (mutex mutex-get) > (cond cond-get) > (q q-get)) > > > (define (make-async-queue) > (_make-async-queue (make-mutex) > (make-condition-variable) > (make-q))) > > (define (async-queue-pop! a-q) > (let ([mutex (mutex-get a-q)]) > (with-mutex mutex > (let ([q (q-get a-q)]) > (let loop () > (if (q-empty? q) > (begin > (wait-condition-variable (cond-get a-q) mutex) > (loop)) > (deq! q))))))) > > (define (async-queue-push! a-q item) > (with-mutex (mutex-get a-q) > (enq! (q-get a-q) item)) > (signal-condition-variable (cond-get a-q))) > > >