[plt-scheme] Thread synchronization for dummies
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
The actual code isn't that long. Here's some example code. It starts
a server thread that accepts action requests: arbitrary functions that
should be run one at a time, and whose return value should be sent
back. It then runs two clients, A and B, which request start and end
messages with a pause in between. The requests will never interleave:
you'll never see a B message in between A start and end messages, and
vice versa.
All you should have to change for your FOO function is the server
function and the client function -- instead of the client sending a
thunk, and the server accepting and running a thunk, replace them with
whatever data structure and action you actually need to process.
#lang scheme
;; SERVER SETUP
(define (server)
(let* ([action (channel-get request-channel)]
[result (action)])
(channel-put response-channel result)
(server)))
(define request-channel (make-channel))
(define response-channel (make-channel))
(define server-thread (thread server))
;; REQUEST FUNCTION
(define (request action)
(channel-put request-channel action)
(channel-get response-channel))
;; CLIENT SETUP
(define (client name)
(lambda ()
(let loop ()
(sleep (random))
(request (lambda ()
(printf "~a: START\n" name)
(sleep (random))
(printf "~a: END\n" name)))
(loop))))
;; TWO SIMULTANEOUS CLIENTS
(thread (client "A"))
(thread (client "B"))
--
Carl Eastlund