1. PROCESS COORDINATION
Process coordination or concurrency control deals with mutual exclusion and synchronization.
Mutual exclusion--ensure that two concurrent activities do not access shared data (resource) at the same time,
critical region--set of instructions that only one process can execute.
Synchronization--using a condition to coordinate the actions of concurrent activities. A generalization of mutual
exclusion.
When considering process coordination, we must keep in mind the following situations:
1.
Deadlock occurs when two activities are waiting each other and neither can proceed. For example:
Suppose processes A and B each need two tape drives to continue, but only one drive has been assigned
to each of them. If the system has only 2 drives, neither process can ever proceed.
2.
Starvation occurs when a blocked activity is consistently passed over and not allowed to run. For
example:
Consider two cpu bound jobs, one running at a higher priority than the other. The lower priority process
will never be allowed to execute. As we shall see, some synchronization primitives lead to starvation.
PROCESS SYNCHRONIZATION
Process Synchronization means sharing system resources by processes in a such a way that, Concurrent access
to shared data is handled thereby minimizing the chance of inconsistent data. Maintaining data consistency
demands mechanisms to ensure synchronized execution of cooperating processes.
Process Synchronization was introduced to handle problems that arose while multiple process executions. Some
of the problems are discussed below.
Critical Section Problem
A Critical Section is a code segment that accesses shared variables and has to be executed as an atomic action.
It means that in a group of cooperating processes, at a given point of time, only one process must be executing
its critical section. If any other process also wants to execute its critical section, it must wait until the first one
finishes.
Solution to Critical Section Problem
A solution to the critical section problem must satisfy the following three conditions:
2. 1. Mutual Exclusion: Out of a group of cooperating processes, only one process can be in its critical section at
a given point of time.
2. Progress: If no process is in its critical section, and if one or more threads want to execute their critical
section then any one of these threads must be allowed to get into its critical section.
3. Bounded Waiting: After a process makes a request for getting into its critical section, there is a limit for how
many other processes can get into their critical section, before this process's request is granted. So after the limit
is reached, system must grant the process permission to get into its critical section.
INTRODUCTION TO SEMAPHORES
In 1965, Dijkstra proposed a new and very significant technique for managing concurrent processes by using
the value of a simple integer variable to synchronize the progress of interacting processes. This integer variable
is called semaphore. So it is basically a synchronizing tool and is accessed only through two low standard
atomic operations, wait and signal designated by P(S) and V(S)respectively.
In very simple words, semaphore is a variable which can hold only a non-negative Integer value, shared
between all the threads, with operations wait and signal, which work as follow:
P(S): if S ≥ 1 then S: = S - 1
else <block and enqueue the process>;
V(S): if <some process is blocked on the queue>
then <unblock a process>
else S:= S + 1;
Properties of Semaphores
It's simple and always having a non-negative Integer value.
It works with many processes.
It can have many different critical sections with different semaphores.
Each critical section has unique access semaphores.
It can permit multiple processes into the critical section at once, if desirable.
Types of Semaphores
Semaphores are mainly of two types:
1. Binary Semaphore: It is a special form of semaphore used for implementing mutual exclusion; hence it
is often called a Mutex. A binary semaphore is initialized to 1 and only takes the values 0 and 1 during
execution of a program. They are also known as mutex locks, as the locks can provide mutual exclusion.
All the processes can share the same mutex semaphore that is initialized to 1. Then, a process has to wait
until the lock becomes 0. Then, the process can make the mutex semaphore 1 and start its critical
section. When it completes its critical section, it can reset the value of mutex semaphore to 0 and some
other process can enter its critical section.
2. Counting Semaphores: These are used to implement bounded concurrency. They can have any value and
are not restricted over a certain domain. They can be used to control access a resource that has a
limitation on the number of simultaneous accesses. The semaphore can be initialized to the number of
instances of the resource. Whenever a process wants to use that resource, it checks if the number of
remaining instances is more than zero, i.e., the process has an instance available. Then, the process can
enter its critical section thereby decreasing the value of the counting semaphore by 1. After the process
3. is over with the use of the instance of the resource, it can leave the critical section thereby adding 1 to
the number of available instances of the resource.
Limitations of Semaphores
1. Priority Inversion is a big limitation of semaphores.
2. Their use is not enforced, but is by convention only.
3. With improper use, a process may block indefinitely. Such a situation is called Deadlock. We will
be studying deadlocks in details in coming lessons.
CLASSICAL PROBLEMS OF SYNCHRONIZATION
In this tutorial we will discuss about various classic problem of synchronization.
Semaphore can be used in other synchronization problems besides Mutual Exclusion.
Below are some of the classical problem depicting flaws of process synchronaization in systems where
cooperating processes are present.
We will discuss the following three problems:
1. Bounded Buffer (Producer-Consumer) Problem
2. The Readers Writers Problem
3. Dining Philosophers Problem
MONITORS
A monitor is a programming language construct that controls access to shared data. Monitors are abstract data
types and contain shared data variables and procedures. The shared data variables cannot be directly accessed
by a process and procedures are required to allow a single process to access the shared data variables at a time.
It is a module that encapsulates
• Shared data structures
• Procedures that operate on the shared data structures
• Synchronization between concurrent procedure invocations
A monitor protects its data from unstructured access. It guarantees that threads accessing its data through its
procedures interact only in legitimate ways.
A monitor guarantees mutual exclusion
• Only one thread can execute any monitor procedure at any time (the thread is “in the monitor”)
• If a second thread invokes a monitor procedure when a first thread is already executing one, it blocks »
So the monitor has to have a wait queue…
• If a thread within a monitor blocks, another one can enter.
Only one process can be active in a monitor at a time. Other processes that need to access the shared variables
in a monitor have to line up in a queue and are only provided access when the previous process releases the
shared variables.
4. SYNCHRONIZATION
It is a process that involves coordinating the execution of multiple threads to ensure a desired outcome without
corrupting the shared data and preventing any occurrence of deadlocks and race conditions.
In computer science, synchronization refers to one of two distinct but related concepts:
• Process synchronization refers to the idea that multiple processes are to join up or handshake at a certain
point, in order to reach an agreement or commit to a certain sequence of action.
• Data synchronization refers to the idea of keeping multiple copies of a dataset in coherence with one
another, or to maintain data integrity. Process synchronization primitives are commonly used to
implement data synchronization.
ATOMIC TRANSACTION
Atomic operations in concurrent programming are program operations that run completely independently of any
other process
Atomic operations are used in many modern operating systems and parallel processing systems.
Atomic operations are often used in the kernel, the primary component of most operating systems. However,
most computer hardware, compilers and libraries also provide varying levels of atomic operations.
In loading and storing, computer hardware carries out writing and reading to a word-sized memory. To fetch,
add or subtract, value augmentation takes place through atomic operations. During an atomic operation, a
processor can read and write a location during the same data transmission. In this way, another input/output
mechanism or processor cannot perform memory reading or writing tasks until the atomic operation has
finished.
Where data is being used by an atomic operation that is also in use by other atomic or non-atomic operations, it
can only exist in either sequential processing environments or locking mechanisms have to be used to avoid
data errors. Compare and swap is another method but does not guarantee data integrity for atomic operation
results.
The problem comes when two operations running in parallel (concurrent operations) utilise the same data and a
disparity between the results of the operations occurs. Locking locks variable data and forces sequential
operation of atomic processes that utilize the same data or affect it in some way.
DEADLOCK
Deadlocks are a set of blocked processes each holding a resource and waiting to acquire a resource held by
another process.
5. Deadlock Prevention, Avoidance, Detection And Recovery In Operating Systems
Deadlock Problem: In a computer system deadlocks arise when members of a group of processes which hold
resources are blocked indefinitely from access to resources held by other processes within the group.
Deadlock Characterization
How to avoid Deadlocks
Deadlocks can be avoided by avoiding at least one of the four conditions, because all this four conditions are
required simultaneously to cause deadlock.
1. Mutual Exclusion: Resources shared such as read-only files do not lead to deadlocks but resources,
such as printers and tape drives, requires exclusive access by a single process.
2. Hold and Wait: In this condition processes must be prevented from holding one or more resources
while simultaneously waiting for one or more others.
3. No Preemption: Preemption of process resource allocations can avoid the condition of deadlocks,
where ever possible.
4. Circular Wait: Circular wait can be avoided if we number all resources, and require that processes
request resources only in strictly increasing (or decreasing) order.
Handling Deadlock
The above points focus on preventing deadlocks. But what to do once a deadlock has occurred. Following three
strategies can be used to remove deadlock after its occurrence.
1. Preemption: We can take a resource from one process and give it to other. This will resolve the
deadlock situation, but sometimes it does causes problems.
2. Rollback: In situations where deadlock is a real possibility, the system can periodically make a record
of the state of each process and when deadlock occurs, roll everything back to the last checkpoint, and
restart, but allocating resources differently so that deadlock does not occur.
3. Kill one or more processes: This is the simplest way, but it works.
6. Deadlock Detection
If deadlock prevention and avoidance are not done properly, as deadlock may occur and only things left to do is
to detect the recover from the deadlock.
If all resource types has only single instance, then we can use a graph called wait-for-graph, which is a variant
of resource allocation graph. Here, vertices represent processes and a directed edge from P1 to P2 indicate that
P1 is waiting for a resource held by P2. Like in the case of resource allocation graph, a cycle in a wait-for-
graph indicate a deadlock. So the system can maintain a wait-for-graph and check for cycles periodically to
detect any deadlocks.
The wait-for-graph is not much useful if there are multiple instances for a resource, as a cycle may not imply a
deadlock. In such a case, we can use an algorithm similar to Banker’s algorithm to detect deadlock. We can see
if further allocations can be made on not based on current allocations. You can refer to any operating system
text books for details of these algorithms.
Deadlock Recovery
Once a deadlock is detected, you will have to break the deadlock. It can be done through different ways,
including, aborting one or more processes to break the circular wait condition causing the deadlock and
preempting resources from one or more processes which are deadlocked.
SYSTEM MODELING
It is the process of developing abstract models of a system, with each model presenting a different view or
perspective of that system. It is about representing a system using some kind of graphical notation, which is
now almost always based on notations in the Unified Modeling Language (UML). Models help the analyst to
understand the functionality of the system; they are used to communicate with customers.
Models can explain the system from different perspectives:
• An external perspective, where you model the context or environment of the system.
• An interaction perspective, where you model the interactions between a system and its environment,
or between the components of a system.
• A structural perspective, where you model the organization of a system or the structure of the data
that is processed by the system.
• A behavioral perspective, where you model the dynamic behavior of the system and how it responds
to events.
Five types of UML (Unified Modeling Language) diagrams that are the most useful for system modeling:
• Activity diagrams, which show the activities involved in a process or in data processing.
• Use case diagrams, which show the interactions between a system and its environment.
7. • Sequence diagrams, which show interactions between actors and the system and between system
components.
• Class diagrams, which show the object classes in the system and the associations between these
classes.
• State diagrams, which show how the system reacts to internal and external events.
Models of both new and existing system are used during requirements engineering. Models of the existing
systems help clarify what the existing system does and can be used as a basis for discussing its strengths and
weaknesses. These then lead to requirements for the new system. Models of the new systemare used during
requirements engineering to help explain the proposed requirements to other system stakeholders. Engineers use
these models to discuss design proposals and to document the system for implementation.