This project is about the process of implement the 'Starting gun' and 'Shutting down' logic for detached threads.
Software Used
Languages Used
Visual Studio
C++
Explanations
Synchronization
Deadlocks
Thread Types
Mutex
Condition Variables
Synchronization Primitives
Deadlocks
When dealing with threads and the need to access multiple mutex-protected resources, there is the possibility for “deadlock” to occur. Deadlock (sometimes called “deadly embrace”) is a situation where two or more competing actions are waiting for the other to finish, and thus neither ever does. To illustrate this, we are going to write code to run a drinking game.
Usage: DrinkingGame drinkerCount bottleCount openerCount
Arguments:
drinker Count Number of drinkers.
bottle Count Number of bottles.
opener Count Number of openers.
The drinking game consists of Drinkers, Bottles, and Bottle Openers. During the gameplay drinkers will be constantly trying to drink, which consists of acquiring a bottle and an opener resource. Once a drinker is able to successfully acquire both resources it will take a drink, sleep for a while, then release both resources so another drinker can use them.
When trying to get the resources one of two things may happen: the drinker acquires both resources or the drinker fails to get any resources. Each resource has a mutex that determines if it's currently in use - if it's locked then it's being used by a drinker. The drinker will randomly pick a bottle or an opener as its first resource and lock it. Once the drinker has the first resource it will need to look through the entire pool of resources for the second resource. If the drinker had a bottle as the first resource then it will need to look for an unused opener. It is possible that the drinker cannot find the second resource - in this case the drinker has failed to get both resources.
Synchronization
Insure that events in multiple threads always occur in the
correct order
Allow the safe sharing of data between threads
Beware of overuse of synchronization
Thread Types
Joinable – All spawned threads begin as joinable, they need to be declared
as detached or Joined. Once declared they can not be changed.
Joined – A thread that has been declared as joined has a relationship with
the thread that contains the join. The thread with the join will wait at the
place where the join appears for the joined thread to complete before
moving on
Detached - Detached threads are mostly independent of the thread that
spawns them
If you omit this call, the result is undefined
Threads may be scheduled by the system scheduler (OS) or by a scheduler in the thread library (depending on the threading model).
The scheduler in the thread library:
>will preempt currently running threads on the basis of priority
>does NOT time-slice (i.e., is not fair). A running thread will continue to run forever unless:
o a thread call is made into the thread library
o a blocking call is made
o the running thread calls sched_yield()
Managing Dependencies and Protecting Critical Sections
Mutexes
Condition Variables
Reader/Writer Locks
Semaphores
Barriers
A Mutex (Mutual Exclusion) is a data element that allowsmultiple threads to synchronize their access to sharedresources. It is a lockable object that is designed tosignal when critical sections of code need exclusiveaccess, preventing other threads with the sameprotection from executing concurrently and access thesame memory locations.
Like a binary semaphore, a mutex has two states, locked and unlocked
Only one thread can lock a mutex
Once a mutex is locked, other threads will block when they try to lock the same mutex, until the locking mutex unlocks the mutex, at which point one of the waiting thread’s lock will succeed, and the process begins again
Condition Variables
A Condition variable is synchronization mechanism that
allows multiple threads to conditionally wait, until some
defined time at which they can proceed.
Condition variables are different from mutexes because
they don’t protect code, but procedure.
A thread will wait on a condition variable until the
variable signals it can proceed.
Synchronization Primitives
Counting Semaphores
• Permit a limited number of threads to execute a section of the code
Binary Semaphores - Mutexes
• Permit only one thread to execute a section of the code
Condition Variables
• Communicate information about the state of shared data
Deadlocks
When two or more competing processes are waiting for each other to release resources, and neither do
Deadlock Characterization
Mutual exclusion: only one process at a time can use a resource
Hold and wait: a process holding at least one resource is waiting to
acquire additional resources held by other processes
No preemption: a resource can be released only voluntarily by the
process holding it, after that process has completed its task
Circular wait: there exists a set {P0, P1, ..., Pn} of waiting processes
such that P0 is waiting for a resource that is held by P1, P1 is waiting for
a resource that is held by P2, ..., Pn–1 is waiting for a resource that is
held by Pn, and Pn is waiting for a resource that is held by P0.