| <html lang="en"> |
| <head> |
| <title>Streams and Threads - The GNU C Library</title> |
| <meta http-equiv="Content-Type" content="text/html"> |
| <meta name="description" content="The GNU C Library"> |
| <meta name="generator" content="makeinfo 4.13"> |
| <link title="Top" rel="start" href="index.html#Top"> |
| <link rel="up" href="I_002fO-on-Streams.html#I_002fO-on-Streams" title="I/O on Streams"> |
| <link rel="prev" href="Closing-Streams.html#Closing-Streams" title="Closing Streams"> |
| <link rel="next" href="Streams-and-I18N.html#Streams-and-I18N" title="Streams and I18N"> |
| <link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage"> |
| <!-- |
| This file documents the GNU C library. |
| |
| This is Edition 0.12, last updated 2007-10-27, |
| of `The GNU C Library Reference Manual', for version |
| 2.8 (Sourcery G++ Lite 2011.03-41). |
| |
| Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002, |
| 2003, 2007, 2008, 2010 Free Software Foundation, Inc. |
| |
| Permission is granted to copy, distribute and/or modify this document |
| under the terms of the GNU Free Documentation License, Version 1.3 or |
| any later version published by the Free Software Foundation; with the |
| Invariant Sections being ``Free Software Needs Free Documentation'' |
| and ``GNU Lesser General Public License'', the Front-Cover texts being |
| ``A GNU Manual'', and with the Back-Cover Texts as in (a) below. A |
| copy of the license is included in the section entitled "GNU Free |
| Documentation License". |
| |
| (a) The FSF's Back-Cover Text is: ``You have the freedom to |
| copy and modify this GNU manual. Buying copies from the FSF |
| supports it in developing GNU and promoting software freedom.''--> |
| <meta http-equiv="Content-Style-Type" content="text/css"> |
| <style type="text/css"><!-- |
| pre.display { font-family:inherit } |
| pre.format { font-family:inherit } |
| pre.smalldisplay { font-family:inherit; font-size:smaller } |
| pre.smallformat { font-family:inherit; font-size:smaller } |
| pre.smallexample { font-size:smaller } |
| pre.smalllisp { font-size:smaller } |
| span.sc { font-variant:small-caps } |
| span.roman { font-family:serif; font-weight:normal; } |
| span.sansserif { font-family:sans-serif; font-weight:normal; } |
| --></style> |
| <link rel="stylesheet" type="text/css" href="../cs.css"> |
| </head> |
| <body> |
| <div class="node"> |
| <a name="Streams-and-Threads"></a> |
| <p> |
| Next: <a rel="next" accesskey="n" href="Streams-and-I18N.html#Streams-and-I18N">Streams and I18N</a>, |
| Previous: <a rel="previous" accesskey="p" href="Closing-Streams.html#Closing-Streams">Closing Streams</a>, |
| Up: <a rel="up" accesskey="u" href="I_002fO-on-Streams.html#I_002fO-on-Streams">I/O on Streams</a> |
| <hr> |
| </div> |
| |
| <h3 class="section">12.5 Streams and Threads</h3> |
| |
| <p><a name="index-threads-943"></a><a name="index-multi_002dthreaded-application-944"></a>Streams can be used in multi-threaded applications in the same way they |
| are used in single-threaded applications. But the programmer must be |
| aware of the possible complications. It is important to know about |
| these also if the program one writes never use threads since the design |
| and implementation of many stream functions is heavily influenced by the |
| requirements added by multi-threaded programming. |
| |
| <p>The POSIX standard requires that by default the stream operations are |
| atomic. I.e., issuing two stream operations for the same stream in two |
| threads at the same time will cause the operations to be executed as if |
| they were issued sequentially. The buffer operations performed while |
| reading or writing are protected from other uses of the same stream. To |
| do this each stream has an internal lock object which has to be |
| (implicitly) acquired before any work can be done. |
| |
| <p>But there are situations where this is not enough and there are also |
| situations where this is not wanted. The implicit locking is not enough |
| if the program requires more than one stream function call to happen |
| atomically. One example would be if an output line a program wants to |
| generate is created by several function calls. The functions by |
| themselves would ensure only atomicity of their own operation, but not |
| atomicity over all the function calls. For this it is necessary to |
| perform the stream locking in the application code. |
| |
| <!-- stdio.h --> |
| <!-- POSIX --> |
| <div class="defun"> |
| — Function: void <b>flockfile</b> (<var>FILE *stream</var>)<var><a name="index-flockfile-945"></a></var><br> |
| <blockquote><p>The <code>flockfile</code> function acquires the internal locking object |
| associated with the stream <var>stream</var>. This ensures that no other |
| thread can explicitly through <code>flockfile</code>/<code>ftrylockfile</code> or |
| implicit through a call of a stream function lock the stream. The |
| thread will block until the lock is acquired. An explicit call to |
| <code>funlockfile</code> has to be used to release the lock. |
| </p></blockquote></div> |
| |
| <!-- stdio.h --> |
| <!-- POSIX --> |
| <div class="defun"> |
| — Function: int <b>ftrylockfile</b> (<var>FILE *stream</var>)<var><a name="index-ftrylockfile-946"></a></var><br> |
| <blockquote><p>The <code>ftrylockfile</code> function tries to acquire the internal locking |
| object associated with the stream <var>stream</var> just like |
| <code>flockfile</code>. But unlike <code>flockfile</code> this function does not |
| block if the lock is not available. <code>ftrylockfile</code> returns zero if |
| the lock was successfully acquired. Otherwise the stream is locked by |
| another thread. |
| </p></blockquote></div> |
| |
| <!-- stdio.h --> |
| <!-- POSIX --> |
| <div class="defun"> |
| — Function: void <b>funlockfile</b> (<var>FILE *stream</var>)<var><a name="index-funlockfile-947"></a></var><br> |
| <blockquote><p>The <code>funlockfile</code> function releases the internal locking object of |
| the stream <var>stream</var>. The stream must have been locked before by a |
| call to <code>flockfile</code> or a successful call of <code>ftrylockfile</code>. |
| The implicit locking performed by the stream operations do not count. |
| The <code>funlockfile</code> function does not return an error status and the |
| behavior of a call for a stream which is not locked by the current |
| thread is undefined. |
| </p></blockquote></div> |
| |
| <p>The following example shows how the functions above can be used to |
| generate an output line atomically even in multi-threaded applications |
| (yes, the same job could be done with one <code>fprintf</code> call but it is |
| sometimes not possible): |
| |
| <pre class="smallexample"> FILE *fp; |
| { |
| ... |
| flockfile (fp); |
| fputs ("This is test number ", fp); |
| fprintf (fp, "%d\n", test); |
| funlockfile (fp) |
| } |
| </pre> |
| <p>Without the explicit locking it would be possible for another thread to |
| use the stream <var>fp</var> after the <code>fputs</code> call return and before |
| <code>fprintf</code> was called with the result that the number does not |
| follow the word ‘<samp><span class="samp">number</span></samp>’. |
| |
| <p>From this description it might already be clear that the locking objects |
| in streams are no simple mutexes. Since locking the same stream twice |
| in the same thread is allowed the locking objects must be equivalent to |
| recursive mutexes. These mutexes keep track of the owner and the number |
| of times the lock is acquired. The same number of <code>funlockfile</code> |
| calls by the same threads is necessary to unlock the stream completely. |
| For instance: |
| |
| <pre class="smallexample"> void |
| foo (FILE *fp) |
| { |
| ftrylockfile (fp); |
| fputs ("in foo\n", fp); |
| /* <span class="roman">This is very wrong!!!</span> */ |
| funlockfile (fp); |
| } |
| </pre> |
| <p>It is important here that the <code>funlockfile</code> function is only called |
| if the <code>ftrylockfile</code> function succeeded in locking the stream. It |
| is therefore always wrong to ignore the result of <code>ftrylockfile</code>. |
| And it makes no sense since otherwise one would use <code>flockfile</code>. |
| The result of code like that above is that either <code>funlockfile</code> |
| tries to free a stream that hasn't been locked by the current thread or it |
| frees the stream prematurely. The code should look like this: |
| |
| <pre class="smallexample"> void |
| foo (FILE *fp) |
| { |
| if (ftrylockfile (fp) == 0) |
| { |
| fputs ("in foo\n", fp); |
| funlockfile (fp); |
| } |
| } |
| </pre> |
| <p>Now that we covered why it is necessary to have these locking it is |
| necessary to talk about situations when locking is unwanted and what can |
| be done. The locking operations (explicit or implicit) don't come for |
| free. Even if a lock is not taken the cost is not zero. The operations |
| which have to be performed require memory operations that are safe in |
| multi-processor environments. With the many local caches involved in |
| such systems this is quite costly. So it is best to avoid the locking |
| completely if it is not needed – because the code in question is never |
| used in a context where two or more threads may use a stream at a time. |
| This can be determined most of the time for application code; for |
| library code which can be used in many contexts one should default to be |
| conservative and use locking. |
| |
| <p>There are two basic mechanisms to avoid locking. The first is to use |
| the <code>_unlocked</code> variants of the stream operations. The POSIX |
| standard defines quite a few of those and the GNU library adds a few |
| more. These variants of the functions behave just like the functions |
| with the name without the suffix except that they do not lock the |
| stream. Using these functions is very desirable since they are |
| potentially much faster. This is not only because the locking |
| operation itself is avoided. More importantly, functions like |
| <code>putc</code> and <code>getc</code> are very simple and traditionally (before the |
| introduction of threads) were implemented as macros which are very fast |
| if the buffer is not empty. With the addition of locking requirements |
| these functions are no longer implemented as macros since they would |
| expand to too much code. |
| But these macros are still available with the same functionality under the new |
| names <code>putc_unlocked</code> and <code>getc_unlocked</code>. This possibly huge |
| difference of speed also suggests the use of the <code>_unlocked</code> |
| functions even if locking is required. The difference is that the |
| locking then has to be performed in the program: |
| |
| <pre class="smallexample"> void |
| foo (FILE *fp, char *buf) |
| { |
| flockfile (fp); |
| while (*buf != '/') |
| putc_unlocked (*buf++, fp); |
| funlockfile (fp); |
| } |
| </pre> |
| <p>If in this example the <code>putc</code> function would be used and the |
| explicit locking would be missing the <code>putc</code> function would have to |
| acquire the lock in every call, potentially many times depending on when |
| the loop terminates. Writing it the way illustrated above allows the |
| <code>putc_unlocked</code> macro to be used which means no locking and direct |
| manipulation of the buffer of the stream. |
| |
| <p>A second way to avoid locking is by using a non-standard function which |
| was introduced in Solaris and is available in the GNU C library as well. |
| |
| <!-- stdio_ext.h --> |
| <!-- GNU --> |
| <div class="defun"> |
| — Function: int <b>__fsetlocking</b> (<var>FILE *stream, int type</var>)<var><a name="index-g_t_005f_005ffsetlocking-948"></a></var><br> |
| <blockquote> |
| <p>The <code>__fsetlocking</code> function can be used to select whether the |
| stream operations will implicitly acquire the locking object of the |
| stream <var>stream</var>. By default this is done but it can be disabled and |
| reinstated using this function. There are three values defined for the |
| <var>type</var> parameter. |
| |
| <dl> |
| <dt><code>FSETLOCKING_INTERNAL</code><a name="index-FSETLOCKING_005fINTERNAL-949"></a><dd>The stream <code>stream</code> will from now on use the default internal |
| locking. Every stream operation with exception of the <code>_unlocked</code> |
| variants will implicitly lock the stream. |
| |
| <br><dt><code>FSETLOCKING_BYCALLER</code><a name="index-FSETLOCKING_005fBYCALLER-950"></a><dd>After the <code>__fsetlocking</code> function returns the user is responsible |
| for locking the stream. None of the stream operations will implicitly |
| do this anymore until the state is set back to |
| <code>FSETLOCKING_INTERNAL</code>. |
| |
| <br><dt><code>FSETLOCKING_QUERY</code><a name="index-FSETLOCKING_005fQUERY-951"></a><dd><code>__fsetlocking</code> only queries the current locking state of the |
| stream. The return value will be <code>FSETLOCKING_INTERNAL</code> or |
| <code>FSETLOCKING_BYCALLER</code> depending on the state. |
| </dl> |
| |
| <p>The return value of <code>__fsetlocking</code> is either |
| <code>FSETLOCKING_INTERNAL</code> or <code>FSETLOCKING_BYCALLER</code> depending on |
| the state of the stream before the call. |
| |
| <p>This function and the values for the <var>type</var> parameter are declared |
| in <samp><span class="file">stdio_ext.h</span></samp>. |
| </p></blockquote></div> |
| |
| <p>This function is especially useful when program code has to be used |
| which is written without knowledge about the <code>_unlocked</code> functions |
| (or if the programmer was too lazy to use them). |
| |
| </body></html> |
| |