ACA 2024W 03 Shared-Memory Programming 1-35
ACA 2024W 03 Shared-Memory Programming 1-35
Objectives
!
Learn what threads are and how you can create them.
!
Learn how to initialize threads in order to perform a desired task.
!
Learn how to terminate a multi-threaded program using different
techniques.
!
Understand problems associated with having threads access shared
resources, like race-conditions and deadlocks.
!
Learn what semaphores and monitors are and how you can use them in
your programs.
!
Become familiar with classical synchronization problems and their
solutions.
!
Learn how threads can be dynamically managed at run-time.
!
Learn effective debugging techniques for multi-threaded programs.
<C> G. Barlas, 2015 2
Introduction
!
Thread: An execution path (a sequence of instructions)
that is managed separately by the operating system
scheduler as a unit. There can be multiple threads per
process.
!
Threads are good for:
− Improving performance
− Background tasks
− Asynchronous processing
− Improving program structure
Thread Creation
!
Traditionally, threads are handled by third-party libraries, such
as:
− pThreads: A C-based library that is considered the common
dominator for threading support.
− winThreads: A Windows-only C++ based library.
− Qt threads: A part of the Qt cross-platform C++ toolkit.
!
C++ 11 standard (ISO/IEC 14882:2011 of year 2011) includes
a build-in thread library.
!
However, some higher level functionality is missing from the
standard.
return 0;
<C> G. Barlas, 2015 5
}
Thread Creation in Qt
! Qt thread management is almost identical to Java's.
! Example:
!
Questions:
− How do we pass parameters?
− How do we detect when the thread is done?
− How do we collect the result?
<C> G. Barlas, 2015 8
Implicit Threads in Qt (cont.)
! Parameters to the function to be run by a thread,
can be added to the invocation to
QtConcurrent::run().
! The run() returns a reference to an instance of the
QFuture class.
! QFuture provides:
− isStarted()
− isRunning()
− isFinished()
! A sample run:
!
A semaphore is a software abstraction proposed by the late Dutch
computer scientist Edsger Dijkstra, that supports two atomic
operations:
– P for "try to decrement". If the semaphore is unlocked (new value is
non-negative) it becomes locked. If it is locked (new value is non-
positive) the operation is blocking.
– V for "increment".
! Semaphores are equipped with a queue for holding blocked
threads. If the queue is a FIFO queue the semaphore is called
strong (or weak otherwise)
! A binary semaphore (a.k.a. mutex, coming from mutal exclusion)
can have only two states. Blocking occurs if the old value is false.
<C> G. Barlas, 2015 17
Semaphore Classes in Qt
= Counting Semaphore
Producers-Consumers
(Code with Sync. for n prod., m cons.)
Termination Problem
Monitors (2)
• Qt provides one more class that simplifies the manage-
ment of the entry-controlling mutex: QMutexLocker.
• An instance of this class should be created at the very first
line of each monitor method. Its responsibility is to lock the
entry-controlling mutex, and that is why its constructor is
passed a reference to it.
• The benefit of this seemingly redundant act is that a
monitor method can terminate at multiple program positions
without requiring an explicit mutex unlock.
• When the destructor of the QMutexLocker class is called
(upon method termination), the mutex is unlocked, saving
effort and eliminating potential programming errors.
A sample run
Map-reduce
! QtConcurrent::mappedReduced() and
QtConcurrent::blockingMappedReduced() functions
! Two phases applied, requiring two functions: one for the
mapping and one for the reduction.
! Reduction function signature:
A Case Study:
Multithreaded Image Matching (2)
! Look at Code image_matching/main.cpp.
– Uses QtConcurrent::blockingMap
– Uses the template class QThreadStorage for holding
data in an object or class that is thread specific. Useful
methods of QThreadStorage:
• bool hasLocalData(): returns true if a data item has been
stored on behalf of the current thread
• T localData(): retrieves the data item corresponding to the
currently running thread
• void setLocalData(T): // associates a data item with the
currently running thread
<C> G. Barlas, 2015 52
A Case Study:
Multithreaded Image Matching (3)
! Average Speedup over 10 runs of each scenario.
1,32
1,3
1,28
speedup
1,26
1,24
1,22
1,2
0 50 100 150 200 250 300
Images
<C> G. Barlas, 2015 53
A Case Study:
Multithreaded Image Matching (4)
! Average Speedup over 10 runs of each scenario.
! Without 9 lines of code below comment "read the target
and all other images".