Programming with Sikander
Corporate Trainer: C, Modern C++, Python, Linux System Prog
YouTube :
https://www.youtube.com/playlist?list=PLXfErIZsDibZTMKS-istzXHTTlbS0U37O
1
Multithreading
Original C++ Standard supported only
single thread programming.
The new C++ Standard, C++11, a new
thread library is introduced.
In every C++ application there is one
default main thread i.e. main() function.
We can create additional threads by
creating objects of std::threadclass.
Each of the std::thread object can be
associated with a thread.
Programming with Sikander : Modern C++: Multithreading 2
Thread Creation
To start a thread we simply need to create
a new thread object and pass the
executing code to be called (i.e, a callable
object) into the constructor of the object.
Once the object is created a new thread is
launched which will execute the code
specified in callable.
The callable can be
▪
Address of function / Lambda Expression
▪
Function Object (Member Function)
Programming with Sikander : Modern C++: Multithreading 3
Waiting for threads to finish
Once a thread has started we may need to wait
for the thread to finish before we can take some
action.
To wait for a thread use the std::thread::join()
function.
This function makes the current thread wait until
the thread identified by *thishas finished
executing.
Programming with Sikander : Modern C++: Multithreading 4
Thread creation –Global Function
Programming with Sikander : Modern C++: Multithreading 5
If a thread object is not initialized, it can
be assigned at a later stage.
Programming with Sikander : Modern C++: Multithreading 6
Differentiating between threads
Every running thread has an id.
Thread id can be obtained using get_id
method.
To refer to current thread: this_thread.
Every process starts a new thread
generally referred as the main thread.
Programming with Sikander : Modern C++: Multithreading 7
Programming with Sikander : Modern C++: Multithreading 8
Programming with Sikander : Modern C++: Multithreading 9
Difference between function call
and Thread
Programming with Sikander : Modern C++: Multithreading 10
Multiple threads running parallel
Programming with Sikander : Modern C++: Multithreading 11
Argument Passing to thread
Programming with Sikander : Modern C++: Multithreading 12
Passing Multiple arguments
Programming with Sikander : Modern C++: Multithreading 13
Two threads running on same
function
Programming with Sikander : Modern C++: Multithreading 14
What is the output?
Programming with Sikander : Modern C++: Multithreading 15
What is the output?
Programming with Sikander : Modern C++: Multithreading 16
Passing argument by reference
Programming with Sikander : Modern C++: Multithreading 17
Starting a Thread with a Member
Function
◼
Starting a thread with a member function
of a class requires special attention.
Programming with Sikander : Modern C++: Multithreading 18
◼
Thread Initialization
Programming with Sikander : Modern C++: Multithreading 19
Data Sharing and Race Conditions
In multithreading environment data sharing
between threads is very easy.
But this easy sharing of data can cause
problems in application.
One such problem isRace Condition.
Programming with Sikander : Modern C++: Multithreading 20
What is the output?
Programming with Sikander : Modern C++: Multithreading 21
What is the output?
Programming with Sikander : Modern C++: Multithreading 22
Race Condition
When two or more threads perform a set of
operations in parallel, that access the same
memory location.
Also, one or more thread out of them modifies
the data in that memory location, then this can
lead to an unexpected results some times.
This is called race condition.
Race conditions are usually hard to find because
they don’t occur every time.
They will occur only when relative order of
execution of operations by two or more threads
leads to an unexpected result.
Programming with Sikander : Modern C++: Multithreading 23
Race Condition
Programming with Sikander : Modern C++: Multithreading 24
Fixing Race Condition
•
To fix race conditions in multi-threaded
environment we need mutex.
•
Each thread needs to lock a mutex before
modifying or reading the shared data and after
modifying the data each thread should unlock the
mutex.
•
The mutexes are in the <mutex> header file.
•
The class representing a mutex is the std::mutex
class.
•
There are two important methods ofmutex:
1.) lock()
2.) unlock()
Programming with Sikander : Modern C++: Multithreading 25
Mutex
Amutexis alockable objectthat is
designed to signal when critical sections
of code need exclusive access, preventing
other threads with the same protection
from executing concurrently and access
the same memory locations.
Programming with Sikander : Modern C++: Multithreading 26
Programming with Sikander : Modern C++: Multithreading 27
What will happen when you forget to
unlock a mutex.
Programming with Sikander : Modern C++: Multithreading 28
Programming with Sikander : Modern C++: Multithreading 29
Mutex Management
◼
◼
Programming with Sikander : Modern C++: Multithreading 30
std::lock_guard
•
A C++ Standard Library class for automatic locking
and unlocking of mutexes.
•
Simple ownership model: Lock acquired on
construction, released on destruction
Example:
#include <mutex>
std::mutex myMutex;
std::lock_guard<std::mutex> lock(myMutex);
// ... critical section ...
// lock automatically released upon scope exit
Programming with Sikander : Modern C++: Multithreading 31
std::lock_guard
lock_guardwraps the mutex inside it’s object
and locks the attached mutex in its constructor.
When it’s destructor is called it releases the
mutex.
In this way, it guarantees themutex objectis
properly unlocked in case an exception is
thrown.
Programming with Sikander : Modern C++: Multithreading 32
std::lock_guard
Programming with Sikander : Modern C++: Multithreading 33
•
Advantages:
•
Straightforward usage.
•
Minimal code for basic locking scenarios.
•
Limitations:
•
Lack of advanced features like deferred
locking.
Programming with Sikander : Modern C++: Multithreading 34
std::lock_guard
Std::unique_lock
Aunique lockis an object that manages
amutex objectwithunique ownership.
On construction, the object acquires
amutex object, for whose locking and
unlocking operations becomes responsible.
The object supports bothstates:lockedand
unlocked.
This class guarantees an unlocked status on
destruction (even if not called explicitly).
Programming with Sikander : Modern C++: Multithreading 35
Unique Lock
Programming with Sikander : Modern C++: Multithreading 36
Future
Futures are a high level mechanism for
passing a value between threads, and
allow a thread to wait for a result to be
available without having to manage the
locks directly.
One use of a future is to hold the result of
a call to the new asyncfunction for
running some code asynchronously
Programming with Sikander : Modern C++: Multithreading 37
Programming with Sikander : Modern C++: Multithreading 38
future<int> f=async(launch::async, calculate, 5);
future<int> f=async(launch::deferred, calculate, 5);
Programming with Sikander : Modern C++: Multithreading 39
std::promise
◼
std::promise is a C++ Standard Library class
that provides a simple mechanism for
asynchronous communication between
threads.
◼
A std::promise object represents a promise
for a value that will be made available in the
future.
◼
It is typically used in conjunction with a
std::future object, which is used to retrieve
the value at a later point in the program's
execution.
Programming with Sikander : Modern C++: Multithreading 40
Programming with Sikander : Modern C++: Multithreading 41
THANK YOU
Programming with Sikander : Modern C++: Multithreading 42