Changeset d4d4ac8


Ignore:
Timestamp:
Oct 10, 2021, 5:11:28 PM (7 weeks ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
a73c16e
Parents:
321a1b15
Message:

remove discussion of I/O acquire and replace with mutex statement, add section on string stream

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/user/user.tex

    r321a1b15 rd4d4ac8  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Mon May 31 09:03:34 2021
    14 %% Update Count     : 5071
     13%% Last Modified On : Sun Oct 10 12:45:00 2021
     14%% Update Count     : 5095
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    44444444\CFA provides a fine-grained solution where a \Index{recursive lock} is acquired and released indirectly via a manipulator ©acquire© or instantiating an \Index{RAII} type specific for the kind of stream: ©osacquire©\index{ostream@©ostream©!osacquire@©osacquire©} for output streams and ©isacquire©\index{isacquire@©isacquire©}\index{istream@©istream©!isacquire@©isacquire©} for input streams.
    44454445
    4446 The common usage is manipulator ©acquire©\index{ostream@©ostream©!acquire@©acquire©} to lock a stream during a single cascaded I/O expression, with the manipulator appearing as the first item in a cascade list, \eg:
    4447 \begin{cfa}
    4448 $\emph{thread\(_1\)}$ : sout | ®acquire® | "abc " | "def ";   // manipulator
    4449 $\emph{thread\(_2\)}$ : sout | ®acquire® | "uvw " | "xyz ";
     4446The common usage is the short form of the mutex statement\index{ostream@©ostream©!mutex@©mutex©} to lock a stream during a single cascaded I/O expression, \eg:
     4447\begin{cfa}
     4448$\emph{thread\(_1\)}$ : ®mutex()® sout | "abc " | "def ";
     4449$\emph{thread\(_2\)}$ : ®mutex()® sout | "uvw " | "xyz ";
    44504450\end{cfa}
    44514451Now, the order of the thread execution is still non-deterministic, but the output is constrained to two possible lines in either order.
     
    44664466In summary, the stream lock is acquired by the ©acquire© manipulator and implicitly released at the end of the cascaded I/O expression ensuring all operations in the expression occur atomically.
    44674467
    4468 To lock a stream across multiple I/O operations, an object of type ©osacquire© or ©isacquire© is declared to implicitly acquire/release the stream lock providing mutual exclusion for the object's duration, \eg:
    4469 \begin{cfa}
    4470 {       // acquire sout for block duration
    4471         ®osacquire® acq = { sout };                             $\C{// named stream locker}$
     4468To lock a stream across multiple I/O operations, he long form of the mutex statement is used, \eg:
     4469\begin{cfa}
     4470®mutex( sout )® {
    44724471        sout | 1;
    4473         sout | ®acquire® | 2 | 3;                               $\C{// unnecessary, but ok to acquire and release again}$
     4472        ®mutex() sout® | 2 | 3;                         $\C{// unnecessary, but ok because of recursive lock}$
    44744473        sout | 4;
    4475 }       // implicitly release the lock when "acq" is deallocated
    4476 \end{cfa}
    4477 Note, the unnecessary ©acquire© manipulator works because the recursive stream-lock can be acquired/released multiple times by the owner thread.
     4474} // implicitly release sout lock
     4475\end{cfa}
     4476Note, the unnecessary ©mutex© in the middle of the mutex statement, works because the recursive stream-lock can be acquired/released multiple times by the owner thread.
    44784477Hence, calls to functions that also acquire a stream lock for their output do not result in \Index{deadlock}.
    44794478
    44804479The previous values written by threads 1 and 2 can be read in concurrently:
    44814480\begin{cfa}
    4482 {       // acquire sin lock for block duration
    4483         ®isacquire acq = { sin };®                              $\C{// named stream locker}$
     4481®mutex( sin )® {
    44844482        int x, y, z, w;
    44854483        sin | x;
    4486         sin | ®acquire® | y | z;                                $\C{// unnecessary, but ok to acquire and release again}$
     4484        ®mutex() sin® | y | z;                          $\C{// unnecessary, but ok because of recursive lock}$
    44874485        sin | w;
    4488 }       // implicitly release the lock when "acq" is deallocated
     4486} // implicitly release sin lock
    44894487\end{cfa}
    44904488Again, the order of the reading threads is non-deterministic.
     
    44934491\Textbf{WARNING:} The general problem of \Index{nested locking} can occur if routines are called in an I/O sequence that block, \eg:
    44944492\begin{cfa}
    4495 sout | ®acquire® | "data:" | rtn( mon );        $\C{// mutex call on monitor}$
     4493®mutex() sout® | "data:" | rtn( mon );  $\C{// mutex call on monitor}$
    44964494\end{cfa}
    44974495If the thread executing the I/O expression blocks in the monitor with the ©sout© lock, other threads writing to ©sout© also block until the thread holding the lock is unblocked and releases it.
     
    45004498\begin{cfa}
    45014499int ®data® = rtn( mon );
    4502 sout | acquire | "data:" | ®data®;
     4500mutex() sout | "data:" | ®data®;
    45034501\end{cfa}
    45044502
     
    45064504\section{String Stream}
    45074505
    4508 All the stream formatting capabilities are available to format text to/from a C string rather than to a stream file.
    4509 \VRef[Figure]{f:StringStreamProcessing} shows writing (output) and reading (input) from a C string.
     4506The stream types ©ostrstream© and ©istrstream© provide all the stream formatting capabilities to/from a C string rather than a stream file.
     4507\VRef[Figure]{f:StringStreamProcessing} shows writing (output) to and reading (input) from a C string.
     4508The only string stream operations different from a file stream are:
     4509\begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt]
     4510\item
     4511constructors to create a stream that writes to a write buffer (©ostrstream©) of ©size©, or reads from a read buffer (©istrstream©) containing a C string terminated with ©'\0'©.
     4512\begin{cfa}
     4513void ?{}( ostrstream &, char buf[], size_t size );
     4514void ?{}( istrstream & is, char buf[] );
     4515\end{cfa}
     4516\item
     4517\Indexc{write} (©ostrstream© only) writes all the buffered characters to the specified stream (©stdout© default).
     4518\begin{cfa}
     4519ostrstream & write( ostrstream & os, FILE * stream = stdout );
     4520\end{cfa}
     4521There is no ©read© for ©istrstream©.
     4522\end{itemize}
     4523
    45104524\begin{figure}
    45114525\begin{cfa}
     
    45204534        double x = 12345678.9, y = 98765.4321e-11;
    45214535
    4522         osstr | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y)); $\C{// same lines of output}$
    4523         write( osstr );
    4524         printf( "%s", buf );
    4525         sout | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y));
    4526 
    4527         char buf2[] = "12 14 15 3.5 7e4"; $\C{// input buffer}$
     4536        osstr | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y)) | "abc";
     4537        write( osstr ); $\C{// write string to stdout}$
     4538        printf( "%s", buf ); $\C{// same lines of output}$
     4539        sout | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y)) | "abc";
     4540
     4541        char buf2[] = "12 14 15 3.5 7e4 abc"; $\C{// input buffer}$
    45284542        ®istrstream isstr = { buf2 };®
    4529         isstr | i | j | k | x | y;
    4530         sout | i | j | k | x | y;
    4531 }
     4543        char s[10];
     4544        isstr | i | j | k | x | y | s;
     4545        sout  | i | j | k | x | y | s;
     4546}
     4547
     45483 0x5          7 1.234568e+07 987.654n abc
     45493 0x5          7 1.234568e+07 987.654n abc
     45503 0x5          7 1.234568e+07 987.654n abc
     455112 14 15 3.5 70000. abc
    45324552\end{cfa}
    45334553\caption{String Stream Processing}
    45344554\label{f:StringStreamProcessing}
    45354555\end{figure}
    4536 
    4537 \VRef[Figure]{f:StringStreamFunctions} shows the string stream operations.
    4538 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt]
    4539 \item
    4540 \Indexc{write} (©ostrstream© only) writes all the buffered characters to the specified stream (©stdout© default).
    4541 \end{itemize}
    4542 The constructor functions:
    4543 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt]
    4544 \item
    4545 create a bound stream to a write buffer (©ostrstream©) of ©size© or a read buffer (©istrstream©) containing a C string terminated with ©'\0'©.
    4546 \end{itemize}
    4547 
    4548 \begin{figure}
    4549 \begin{cfa}
    4550 // *********************************** ostrstream ***********************************
    4551 
    4552 ostrstream & write( ostrstream & os, FILE * stream = stdout );
    4553 
    4554 void ?{}( ostrstream &, char buf[], size_t size );
    4555 
    4556 // *********************************** istrstream ***********************************
    4557 
    4558 void ?{}( istrstream & is, char buf[] );
    4559 \end{cfa}
    4560 \caption{String Stream Functions}
    4561 \label{f:StringStreamFunctions}
    4562 \end{figure}
    4563 
    45644556
    45654557\begin{comment}
Note: See TracChangeset for help on using the changeset viewer.