Some additions.
This commit is contained in:
parent
713c23bb6d
commit
9ea85ca468
|
@ -23,7 +23,7 @@ the thread up and forgets about it.
|
|||
The current thread interface is completely taken from Scheme\ 48. This
|
||||
documentation is an extension of the file \texttt{doc/threads.txt}.
|
||||
|
||||
The thread package is named \texttt{threads}, it has to be opened explicitly.
|
||||
The thread structure is named \texttt{threads}, it has to be opened explicitly.
|
||||
|
||||
\defun {spawn} {thunk [name]} \undefined
|
||||
|
||||
|
@ -72,7 +72,8 @@ Returns a unique identifier for the current thread.
|
|||
Locks are a simple mean for mutual exclusion. They implement a concept
|
||||
commonly known as \textit{semaphores}. Threads can obtain and release
|
||||
locks. If a thread tries to obtain a lock which is held by another
|
||||
thread, the first thread is blocked.
|
||||
thread, the first thread is blocked. To access the following
|
||||
procedures, you must open the structure \texttt{locks}.
|
||||
|
||||
\defun{make-lock} {} {lock}
|
||||
|
||||
|
@ -85,7 +86,7 @@ Returns true iff \var{thing} is a lock.
|
|||
\defun{obtain-lock} {lock} {\undefined}
|
||||
|
||||
Obtain \var{lock}. Causes the thread to block if the lock is held by
|
||||
another thread.
|
||||
a thread.
|
||||
|
||||
\defun{maybe-obtain-lock} {lock} {\boolean}
|
||||
|
||||
|
@ -110,7 +111,8 @@ value this thread is blocked. Multiple threads are allowed to block on
|
|||
a single placeholder. They will continue running after another thread
|
||||
sets the value of the placeholder. Now all reading threads receive the
|
||||
value and continue executing. Setting a placeholder to two different
|
||||
values causes an error.
|
||||
values causes an error. The structure \texttt{placeholders} features
|
||||
the following procedures:
|
||||
|
||||
\defun {make-placeholder} {} {placeholder}
|
||||
|
||||
|
@ -131,14 +133,67 @@ Returns the value of the placeholder. If the placeholder is yet unset,
|
|||
the current thread is blocked until another thread sets the value by
|
||||
means of \ex{placeholder-set!}.
|
||||
|
||||
\section{The event interface to interrupts}
|
||||
\label{sec:event-interf-interr}
|
||||
Scsh provides an synchronous interface to the asynchronous signals
|
||||
delivered by the operation system\footnote{Olin's paper ``Automatic
|
||||
management of operation-system resources'' describes this system in
|
||||
detail.}. The key element in this system is an object called
|
||||
\textit{sigevent}, which corresponds to a single occurence of a
|
||||
signal. A sigevent has two fields: the Unix signal that occurred and a
|
||||
pointer to the next event that occurred. That is, events are kept in a
|
||||
linked list in increasing-time order. Scsh provides various procedures
|
||||
to access this list, they are all procided by the structure
|
||||
\texttt{sigevents}.
|
||||
|
||||
\defun {most-recent-sigevent} {} {sigevent}
|
||||
|
||||
Returns the most recent sigevent, that is, the head of the sigevent
|
||||
list.
|
||||
|
||||
\defun {sigevent?} {object} {\boolean}
|
||||
|
||||
The predicate for sigevents.
|
||||
|
||||
\defun {next-sigevent} {pre-event type} {event}
|
||||
|
||||
Returns the next sigevent of type \texttt{type} after sigevent
|
||||
\texttt{pre-event}. If no such event exists, the procdure blocks.
|
||||
|
||||
\defun {next-sigevent-set} {pre-event set} {event}
|
||||
|
||||
Returns the next sigevent whose type is in \texttt{set} after
|
||||
\texttt{pre-event}. If no such event exists, the procdure blocks.
|
||||
|
||||
\defun {next-sigevent/no-wait} {pre-event type} {event or \sharpf}
|
||||
|
||||
Same as \texttt{next-sigevent}, but returns \sharpf if no appropriate
|
||||
event exists.
|
||||
|
||||
\defun {next-sigevent-set/no-wait} {set pre-event} {event or \sharpf}
|
||||
|
||||
Same as \texttt{next-sigevent-set}, but returns \sharpf if no appropriate
|
||||
event exists.
|
||||
|
||||
As a small example, consider this piece of code that toggles the
|
||||
variable \texttt{state} by USR1 and USR2:
|
||||
\begin{code}
|
||||
(define state #t)
|
||||
|
||||
(let lp ((sigevent (most-recent-sigevent)))
|
||||
(let ((next (next-sigevent sigevent interrupt/usr1)))
|
||||
(set! state #f)
|
||||
(let ((next (next-sigevent next interrupt/usr2)))
|
||||
(set! state #t)
|
||||
(lp next))))
|
||||
\end{code}
|
||||
\section{Interaction between threads and process state}
|
||||
\label{sec:ps_interac}
|
||||
|
||||
Global process state is a bad thing: it undermines modularity. In the
|
||||
case of concurrency however things get even worse. The simplest
|
||||
example for this it the current working directory. If this is global
|
||||
state, no thread can ever reliably dereference a relative link.
|
||||
example for this it the current working directory. If this would be
|
||||
global state, no thread can ever reliably dereference a relative link.
|
||||
|
||||
Scsh addresses the problem of process state in a uniform way for
|
||||
almost all resources. For every global resource there is a
|
||||
|
|
Loading…
Reference in New Issue