summaryrefslogtreecommitdiffstats
path: root/doc/src/examples/semaphores.qdoc
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/examples/semaphores.qdoc')
-rw-r--r--doc/src/examples/semaphores.qdoc145
1 files changed, 0 insertions, 145 deletions
diff --git a/doc/src/examples/semaphores.qdoc b/doc/src/examples/semaphores.qdoc
deleted file mode 100644
index b6b4d68f9b..0000000000
--- a/doc/src/examples/semaphores.qdoc
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example threads/semaphores
- \title Semaphores Example
-
- The Semaphores example shows how to use QSemaphore to control
- access to a circular buffer shared by a producer thread and a
- consumer thread.
-
- The producer writes data to the buffer until it reaches the end
- of the buffer, at which point it restarts from the beginning,
- overwriting existing data. The consumer thread reads the data as
- it is produced and writes it to standard error.
-
- Semaphores make it possible to have a higher level of concurrency
- than mutexes. If accesses to the buffer were guarded by a QMutex,
- the consumer thread couldn't access the buffer at the same time
- as the producer thread. Yet, there is no harm in having both
- threads working on \e{different parts} of the buffer at the same
- time.
-
- The example comprises two classes: \c Producer and \c Consumer.
- Both inherit from QThread. The circular buffer used for
- communicating between these two classes and the semaphores that
- protect it are global variables.
-
- An alternative to using QSemaphore to solve the producer-consumer
- problem is to use QWaitCondition and QMutex. This is what the
- \l{threads/waitconditions}{Wait Conditions} example does.
-
- \section1 Global Variables
-
- Let's start by reviewing the circular buffer and the associated
- semaphores:
-
- \snippet examples/threads/semaphores/semaphores.cpp 0
-
- \c DataSize is the amout of data that the producer will generate.
- To keep the example as simple as possible, we make it a constant.
- \c BufferSize is the size of the circular buffer. It is less than
- \c DataSize, meaning that at some point the producer will reach
- the end of the buffer and restart from the beginning.
-
- To synchronize the producer and the consumer, we need two
- semaphores. The \c freeBytes semaphore controls the "free" area
- of the buffer (the area that the producer hasn't filled with data
- yet or that the consumer has already read). The \c usedBytes
- semaphore controls the "used" area of the buffer (the area that
- the producer has filled but that the consumer hasn't read yet).
-
- Together, the semaphores ensure that the producer is never more
- than \c BufferSize bytes ahead of the consumer, and that the
- consumer never reads data that the producer hasn't generated yet.
-
- The \c freeBytes semaphore is initialized with \c BufferSize,
- because initially the entire buffer is empty. The \c usedBytes
- semaphore is initialized to 0 (the default value if none is
- specified).
-
- \section1 Producer Class
-
- Let's review the code for the \c Producer class:
-
- \snippet examples/threads/semaphores/semaphores.cpp 1
- \snippet examples/threads/semaphores/semaphores.cpp 2
-
- The producer generates \c DataSize bytes of data. Before it
- writes a byte to the circular buffer, it must acquire a "free"
- byte using the \c freeBytes semaphore. The QSemaphore::acquire()
- call might block if the consumer hasn't kept up the pace with the
- producer.
-
- At the end, the producer releases a byte using the \c usedBytes
- semaphore. The "free" byte has successfully been transformed into
- a "used" byte, ready to be read by the consumer.
-
- \section1 Consumer Class
-
- Let's now turn to the \c Consumer class:
-
- \snippet examples/threads/semaphores/semaphores.cpp 3
- \snippet examples/threads/semaphores/semaphores.cpp 4
-
- The code is very similar to the producer, except that this time
- we acquire a "used" byte and release a "free" byte, instead of
- the opposite.
-
- \section1 The main() Function
-
- In \c main(), we create the two threads and call QThread::wait()
- to ensure that both threads get time to finish before we exit:
-
- \snippet examples/threads/semaphores/semaphores.cpp 5
- \snippet examples/threads/semaphores/semaphores.cpp 6
-
- So what happens when we run the program? Initially, the producer
- thread is the only one that can do anything; the consumer is
- blocked waiting for the \c usedBytes semaphore to be released (its
- initial \l{QSemaphore::available()}{available()} count is 0).
- Once the producer has put one byte in the buffer,
- \c{freeBytes.available()} is \c BufferSize - 1 and
- \c{usedBytes.available()} is 1. At that point, two things can
- happen: Either the consumer thread takes over and reads that
- byte, or the consumer gets to produce a second byte.
-
- The producer-consumer model presented in this example makes it
- possible to write highly concurrent multithreaded applications.
- On a multiprocessor machine, the program is potentially up to
- twice as fast as the equivalent mutex-based program, since the
- two threads can be active at the same time on different parts of
- the buffer.
-
- Be aware though that these benefits aren't always realized.
- Acquiring and releasing a QSemaphore has a cost. In practice, it
- would probably be worthwhile to divide the buffer into chunks and
- to operate on chunks instead of individual bytes. The buffer size
- is also a parameter that must be selected carefully, based on
- experimentation.
-*/