path: root/doc/src/examples/semaphores.qdoc
diff options
authorPaul Olav Tvete <>2012-11-30 13:50:14 +0100
committerThe Qt Project <>2012-11-30 23:56:53 +0100
commite62198967c2a5da4bd7da1c6c4002ca86400a6b7 (patch)
tree2f426061491daff5632620226935989d6bbc1203 /doc/src/examples/semaphores.qdoc
parent4cbe999921be70a7ee10fa63cfb199ce82371bda (diff)
Fix links for threading examples
Change-Id: I498936e91e3bbf5658ea9f3f0eb33cff271a1d62 Reviewed-by: Eskil Abrahamsen Blomfeldt <>
Diffstat (limited to 'doc/src/examples/semaphores.qdoc')
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:
-** This file is part of the documentation of the Qt Toolkit.
-** 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 For further information
-** use the contact form at
-** 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:
- \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.