[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: The equivalent of racket's break-thread in guile?
From: |
Taylan Ulrich B. |
Subject: |
Re: The equivalent of racket's break-thread in guile? |
Date: |
Fri, 31 May 2013 13:20:00 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.3 (berkeley-unix) |
This is only partially relevant to the topic, but I'm very fond of the
run-loop/operation-queue based solution to the problem of ad-hoc
interleaved code execution in a certain thread, should the application
also otherwise lend itself to that generic architecture.
I have some spare time so let me elaborate, whatever it's worth.
There is no real interruption; a queued function on the run-loop will
execute atomically, but if the functions are kept at appropriate sizes
(don't "block the thread" for too long) it works well and is very easy
to use: asynchronous execution is started with e.g. `begin-thread'
wherever desired, and at any point some `begin-in-original-thread'
abstraction can be used to "switch back" to the original thread (by
inserting a function into the front of the execution queue),
"interrupting" its usual flow cleanly at the boundaries of a top-level
function-call in the run-loop (a queued operation), thus a primitive but
intuitive kind of synchronization is automatically achieved, making
further purpose-specific synchronization very easy with plain booleans
and such.
Cheap pseudo-code for a "set-up interface" function on a GUI run-loop:
(letrec
((request (uri-request image-uri))
(cancel #f)
(start-button
(button #:label "Fetch image"
#:action (lambda ()
(button-disable start-button)
(button-enable cancel-button)
(begin-thread
(let ((image-data (request-execute request)))
(begin-in-original-thread
(unless cancel
(button-disable cancel-button)
(display-image image-data))))))))
(cancel-button
(button #:label "Cancel"
#:action (lambda ()
(request-cancel request)
(set! cancel #t)
(button-enable start-button)
(button-disable cancel-button)))))
(display-button start-button)
(display-button cancel-button)
(button-disable cancel-button))
Since the URI request is executed in parallel, a race might happen with
regard to it finishing and being canceled. On the other hand, access to
the `cancel' boolean is synchronous because all bodies of code that use
it are operations queued on the same run-loop (button actions are queued
on the run-loop).
Maybe I'm biased because the bulk of my day-to-day programming consists
of user-interface heavy applications which lend themselves very well to
a run-loop based architecture, and also I'm using a language that isn't
garbage-collected so cleaning up behind a ruthlessly interrupted/killed
thread can be a hassle; but I believe this method of parallelism and
synchronization to be significantly cleaner than manual/actual
interruption of threads. I'm not aware of any Guile library that
implements run-loops and dispatch queues yet; perhaps I should try to
implement one.
Taylan
Re: The equivalent of racket's break-thread in guile?,
Taylan Ulrich B. <=
Re: The equivalent of racket's break-thread in guile?, Ludovic Courtès, 2013/05/31