[plt-scheme] Thread synchronization for dummies

From: Carl Eastlund (carl.eastlund at gmail.com)
Date: Thu May 28 15:35:09 EDT 2009

And here you go.  The define/sync function will define synchronous
functions for you, and there is an example of using it below.  Again,
there are A and B clients, and their start/end messages should never
be interleaved.

#lang scheme

;; Macro for synchronous funcitons
(define-syntax-rule (define/sync (name . args) . body)
  (define name
    (let ([s (make-semaphore 1)])
      (lambda args
        (dynamic-wind
         (lambda () (semaphore-wait s))
         (lambda () . body)
         (lambda () (semaphore-post s)))))))

;; Using the macro
(define/sync (start-and-end name)
  (printf "~a: START\n" name)
  (sleep (random))
  (printf "~a: END\n" name))

;; Using the synchronous funciton:

(define (client-A)
  (start-and-end "A")
  (client-A))

(define (client-B)
  (start-and-end "B")
  (client-B))

(thread client-A)
(thread client-B)

On Thu, May 28, 2009 at 3:27 PM, Carl Eastlund <carl.eastlund at gmail.com> wrote:
> It has been pointed out to me privately that my response isn't really
> answering your question, which is not simply "can threads, channels,
> and other synchronization primitives be strung together to make a
> synchronized function", but rather "is there an automatic way to
> declare a function as synchronous".  I don't believe there is (and
> sorry for my misreading).  However, there is probably a simple (for
> someone familiar with these primitives) way to write a
> define/synchronized macro.  If I can come up with one that you can
> simply copy/paste into your code (and that can later be added to a
> reusable library) I'll let you know.
>
> --Carl
>
> On Thu, May 28, 2009 at 3:17 PM, Carl Eastlund <carl.eastlund at gmail.com> wrote:
>> On Thu, May 28, 2009 at 3:04 PM, Erich Rast <erich at snafu.de> wrote:
>>>> d reference material for PLT Scheme's concurrency operations here:
>>>>
>>>> http://docs.plt-scheme.org/reference/concurrency.
>>>>
>>> Yep, I've seen this.
>>>
>>>> What I would suggest for your operation is spawning a dedicated thread
>>>> to handle FOO requests.  Whenever FOO gets called, it should send a
>>>> message to that thread, then block to wait for a response.  That
>>>> thread should wait for requests, and for each one should handle the
>>>> request and send a response before waiting for the next request.  This
>>>> will guarantee each request will be handled in order and will not
>>>> overlap.
>>>>
>>>> Look at the documentation for creating threads (for your request
>>>> thread) and on channels (for sending, waiting for, and receiving
>>>> requests/responses).
>>>
>>> That sounds awfully complicated and I was hoping there was an easier
>>> solution. Anyway, thanks for the advice and I'll dig some more into the
>>> world of threads/semaphore/mutexes and whatever else there is.
>>>
>>> --Erich


Posted on the users mailing list.