Documentation for the rest.

This commit is contained in:
mainzelm 2001-12-17 09:27:24 +00:00
parent 3d33a64aec
commit 99eaabd0a5
1 changed files with 56 additions and 32 deletions

View File

@ -2,17 +2,17 @@
\chapter{Concurrent system programming}
The Scheme Shell provides you with support for concurrent programming.
Its interface for concurrent programming consists of several parts:
The Scheme Shell provides the user with support for concurrent programming.
The interface consists of several parts:
\begin{itemize}
\item The thread system
\item Synchronization vehicles
\item Process state abstractions
\end{itemize}
Whereas the user deals with threads and synchronization explicitly, the
process state abstractions are built into the rest of the system
transparent for the user. Section \ref{sec:ps_interac} describes the
interaction between process state and threads.
Whereas the user deals with threads and synchronization explicitly,
the process state abstractions are built into the rest of the system,
almost transparent for the user. Section \ref{sec:ps_interac}
describes the interaction between process state and threads.
\section{Threads}
@ -30,7 +30,12 @@ The thread structure is named \texttt{threads}, it has to be opened explicitly.
Create and schedule a new thread that will execute \var{thunk}, a
procedure with no arguments. Note that Scsh's \ex{spawn} does
\textbf{not} return a reference to a thread object. The optional
argument \var{name} is used when printing the thread.
argument \var{name} is used when printing the thread.
The new thread will not inherit the values for the process state from
its parent, see the procedure \texttt{fork-thread} in Section
\ref{sec:ps_interac} for a way to create a thread with
semantics similar to process forking.
\defun {relinquish-timeslice} {} \undefined
@ -139,16 +144,15 @@ 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
\textit{sigevent} which corresponds to the single occurrence 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}.
pointer to the sigevent that happened or will happen. That is, events
are kept in a linked list in increasing-time order. Scsh's structure
\texttt{sigevents} provides various procedures to access this list:
\defun {most-recent-sigevent} {} {sigevent}
Returns the most recent sigevent, that is, the head of the sigevent
Returns the most recent sigevent --- the head of the sigevent
list.
\defun {sigevent?} {object} {\boolean}
@ -158,7 +162,7 @@ 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.
\texttt{pre-event}. If no such event exists, the procedure blocks.
\defun {next-sigevent-set} {pre-event set} {event}
@ -190,24 +194,44 @@ variable \texttt{state} by USR1 and USR2:
\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 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
procedure \ex{with-}\textit{resource}\ex{*} \var{thunk} which guarantees that
during the execution of \var{thunk} the resource is
set to the desired value. There is only one exception: The uid under
which the current process is running. The superuser may change to an
arbitrary user without being prompted for a password, but the way back
is blocked.
In Unix, a number of resources are global to the process: signal
handlers, working directory, umask, environment, user and group ids.
Modular programming is difficult in the context of this global state
and for concurrent programming things get even worse. Section
\ref{sec:event-interf-interr} presents how scsh turns
the global, asynchronous signals handlers into modular, synchronous
sigevents. Concurrent programming also benefit from sigevents as every
thread may chase down the sigevent chain separately.
Scsh treats working directory, umask and environment as a thread-local
resource. The initial value of the resources is determined by the way
a thread is started: \texttt{spawn} assigns the initial values whereas
\texttt{fork-thread} adopts the values of its parent. Here is a
detailed description of the whole facility:
\begin{itemize}
\item The procedures to access and modify the resources remain as
described in the previous chapters (\texttt{cwd} and \texttt{chdir},
\texttt{umask} and \texttt{set-umask}, \texttt{getenv} and
\texttt{putenv}).
\item Every thread receives its own copy of each resource.
\item If \texttt{spawn} is used to start a new thread, the values of
the resources are the same as they where at the start of scsh.
\item The procedure
\defun {fork-thread} {thunk} \undefined
from the structure \texttt{thread-fluids} starts a thread which
inherits the values of all resources from its parent. This behaviour
is similar to what happens at process forking.
\item The actual process state is updated only when necessary, i.e. on
access or modification but not on context switch from one thread
to another.
\end{itemize}
For user and group identities arbitrary changing is not possible.
Therefore they remain global process state: If a thread changes one of
these values, all other threads see the new value. Consequently, scsh
does not provide \texttt{with-uid} and friends.