Update copyright headers
[qt:qt.git] / doc / src / examples / semaphores.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the documentation of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Free Documentation License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Free
19 ** Documentation License version 1.3 as published by the Free Software
20 ** Foundation and appearing in the file included in the packaging of
21 ** this file.  Please review the following information to ensure
22 ** the GNU Free Documentation License version 1.3 requirements
23 ** will be met: http://www.gnu.org/copyleft/fdl.html.
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29     \example threads/semaphores
30     \title Semaphores Example
31
32     \brief The Semaphores example shows how to use QSemaphore to control
33     access to a circular buffer shared by a producer thread and a
34     consumer thread.
35
36     The producer writes data to the buffer until it reaches the end
37     of the buffer, at which point it restarts from the beginning,
38     overwriting existing data. The consumer thread reads the data as
39     it is produced and writes it to standard error.
40
41     Semaphores make it possible to have a higher level of concurrency
42     than mutexes. If accesses to the buffer were guarded by a QMutex,
43     the consumer thread couldn't access the buffer at the same time
44     as the producer thread. Yet, there is no harm in having both
45     threads working on \e{different parts} of the buffer at the same
46     time.
47
48     The example comprises two classes: \c Producer and \c Consumer.
49     Both inherit from QThread. The circular buffer used for
50     communicating between these two classes and the semaphores that
51     protect it are global variables.
52
53     An alternative to using QSemaphore to solve the producer-consumer
54     problem is to use QWaitCondition and QMutex. This is what the
55     \l{threads/waitconditions}{Wait Conditions} example does.
56
57     \section1 Global Variables
58
59     Let's start by reviewing the circular buffer and the associated
60     semaphores:
61
62     \snippet examples/threads/semaphores/semaphores.cpp 0
63
64     \c DataSize is the amout of data that the producer will generate.
65     To keep the example as simple as possible, we make it a constant.
66     \c BufferSize is the size of the circular buffer. It is less than
67     \c DataSize, meaning that at some point the producer will reach
68     the end of the buffer and restart from the beginning.
69
70     To synchronize the producer and the consumer, we need two
71     semaphores. The \c freeBytes semaphore controls the "free" area
72     of the buffer (the area that the producer hasn't filled with data
73     yet or that the consumer has already read). The \c usedBytes
74     semaphore controls the "used" area of the buffer (the area that
75     the producer has filled but that the consumer hasn't read yet).
76
77     Together, the semaphores ensure that the producer is never more
78     than \c BufferSize bytes ahead of the consumer, and that the
79     consumer never reads data that the producer hasn't generated yet.
80
81     The \c freeBytes semaphore is initialized with \c BufferSize,
82     because initially the entire buffer is empty. The \c usedBytes
83     semaphore is initialized to 0 (the default value if none is
84     specified).
85
86     \section1 Producer Class
87
88     Let's review the code for the \c Producer class:
89
90     \snippet examples/threads/semaphores/semaphores.cpp 1
91     \snippet examples/threads/semaphores/semaphores.cpp 2
92
93     The producer generates \c DataSize bytes of data. Before it
94     writes a byte to the circular buffer, it must acquire a "free"
95     byte using the \c freeBytes semaphore. The QSemaphore::acquire()
96     call might block if the consumer hasn't kept up the pace with the
97     producer.
98
99     At the end, the producer releases a byte using the \c usedBytes
100     semaphore. The "free" byte has successfully been transformed into
101     a "used" byte, ready to be read by the consumer.
102
103     \section1 Consumer Class
104
105     Let's now turn to the \c Consumer class:
106
107     \snippet examples/threads/semaphores/semaphores.cpp 3
108     \snippet examples/threads/semaphores/semaphores.cpp 4
109
110     The code is very similar to the producer, except that this time
111     we acquire a "used" byte and release a "free" byte, instead of
112     the opposite.
113
114     \section1 The main() Function
115
116     In \c main(), we create the two threads and call QThread::wait()
117     to ensure that both threads get time to finish before we exit:
118
119     \snippet examples/threads/semaphores/semaphores.cpp 5
120     \snippet examples/threads/semaphores/semaphores.cpp 6
121
122     So what happens when we run the program? Initially, the producer
123     thread is the only one that can do anything; the consumer is
124     blocked waiting for the \c usedBytes semaphore to be released (its
125     initial \l{QSemaphore::available()}{available()} count is 0).
126     Once the producer has put one byte in the buffer,
127     \c{freeBytes.available()} is \c BufferSize - 1 and
128     \c{usedBytes.available()} is 1. At that point, two things can
129     happen: Either the consumer thread takes over and reads that
130     byte, or the consumer gets to produce a second byte.
131
132     The producer-consumer model presented in this example makes it
133     possible to write highly concurrent multithreaded applications.
134     On a multiprocessor machine, the program is potentially up to
135     twice as fast as the equivalent mutex-based program, since the
136     two threads can be active at the same time on different parts of
137     the buffer.
138
139     Be aware though that these benefits aren't always realized.
140     Acquiring and releasing a QSemaphore has a cost. In practice, it
141     would probably be worthwhile to divide the buffer into chunks and
142     to operate on chunks instead of individual bytes. The buffer size
143     is also a parameter that must be selected carefully, based on
144     experimentation.
145 */