Operating System and System Programming_ (2)
Operating System and System Programming_ (2)
Basics:
1. Introduction
2. Types of OS
3. Functions of OS
4. System Initialization
5. Kernel in OS
6. System Call
7. Privileged Instructions
Types of Operating System
Network Management
Security Management
File Management
Error Detection
Job Accounting
Open-source Linux emerged; GUIs in Windows and Mac Linux (1991), Windows 95
1990s
OS improved. (1995)
An operating system is a type of software that acts as an interface between the user and the hardware. It
is responsible for handling various critical functions of the computer and utilizing resources very
efficiently so the operating system is also known as a resource manager. The operating system also acts
like a government because just as the government has authority over everything, similarly the operating
system has authority over all resources. Various tasks that are handled by OS are file management, task
management, garbage management, memory management, process management, disk management, I/O
management, peripherals management, etc.
Generations of Operating Systems
1940s-1950s: Early Beginnings
o Computers operated without operating systems (OS).
o Programs were manually loaded and run, one at a time.
o The first operating system was introduced in 1956. It was a batch processing system GM-
NAA I/O (1956) that automated job handling.
1960s: Multiprogramming and Timesharing
o Introduction of multiprogramming to utilize CPU efficiently.
o Timesharing systems, like CTSS (1961) and Multics (1969), allowed multiple users to
interact with a single system.
1970s: Unix and Personal Computers
o Unix (1971) revolutionized OS design with simplicity, portability, and multitasking.
o Personal computers emerged, leading to simpler OSs like CP/M (1974) and PC-DOS
(1981).
1980s: GUI and Networking
o Graphical User Interfaces (GUIs) gained popularity with systems like Apple Macintosh
(1984) and Microsoft Windows (1985).
o Networking features, like TCP/IP in Unix, became essential.
1990s: Linux and Advanced GUIs
o Linux (1991) introduced open-source development.
o Windows and Mac OS refined GUIs and gained widespread adoption.
2000s-Present: Mobility and Cloud
o Mobile OSs like iOS (2007) and Android (2008) dominate.
o Cloud-based and virtualization technologies reshape computing, with OSs like Windows
Server and Linux driving innovation.
AI Integration – (Ongoing):
With the growth of time, Artificial intelligence came into picture. Operating system integrates
features of AI technology like Siri, Google Assistant, and Alexa and became more powerful and
efficient in many way. These AI features with operating system create a entire new feature like
voice commands, predictive text, and personalized recommendations.
Note: The above mentioned OS basically tells how the OS evolved with the time by adding new features
but it doesn’t mean that only new generation OS are in use and previously OS system are not in use,
according to the need, all these OS are still used in software industry.
Operating systems have evolved from basic program execution to complex ecosystems supporting
diverse devices and users.
Function of Operating System
Memory management
Process management
File management
Device Management
Deadlock Prevention
Input/Output device management
History According to Types of Operating Systems
Operating Systems have evolved in past years. It went through several changes before getting its current
form.
1. No OS – (0s to 1940s)
As we know that before 1940s, there was no use of OS . Earlier, people are lacking OS in their computer
system so they had to manually type instructions for each tasks in machine language(0-1 based language)
. And at that time , it was very hard for users to implement even a simple task. And it was very time
consuming and also not user-friendly. Because not everyone had that much level of understanding to
understand the machine language and it required a deep understanding.
2. Batch Processing Systems -(1950s)
With the growth of time, batch processing system came into the market .Now Users had facility to write
their programs on punch cards and load it to the computer operator. And then operator make different
batches of similar types of jobs and then serve the different batch(group of jobs) one by one to the CPU
.CPU first executes jobs of one batch and them jump to the jobs of other batch in a sequence manner.
3. Multiprogramming Systems -(1960s and 1970s)
Multiprogramming was the first operating system where actual revolution began. It provide user facility
to load the multiple program into the memory and provide a specific portion of memory to each program.
When one program is waiting for any I/O operations (which take much time) at that time the OS give
permission to CPU to switch from previous program to other program(which is first in ready queue) for
continuous execution of program with interrupt.
4. Personal Computers Systems -(1970s)
Unix (1971) revolutionized OS design with simplicity, portability, and multitasking. Personal computers
emerged, leading to simpler OSs like CP/M (1974) and PC-DOS (1981).
5. Introduction of GUI -(1980s)
With the growth of time, Graphical User Interfaces (GUIs) came. First time OS became more user-
friendly and changed the way of people to interact with computer. GUI provides computer system visual
elements which made user’s interaction with computer more comfortable and user-friendly. User can just
click on visual elements rather than typing commands. Here are some feature of GUI in Microsoft’s
windows icons, menus and windows.
6. Networked Systems – (1990s)
At 1980s, the craze of computer networks at it’s peak .A special type of Operating Systems needed to
manage the network communication. The OS like Novell NetWare and Windows NT were developed to
manage network communication which provide users facility to work in collaborative environment and
made file sharing and remote access very easy.
7. Mobile Operating Systems – (2000s)
Invention of smartphones create a big revolution in software industry, To handle the operation of
smartphones , a special type of operating systems were developed. Some of them are : iOS and Android
etc. These operating systems were optimized with the time and became more powerful.
8. AI Integration – (2010s to ongoing)
With the growth of time, Artificial intelligence came into picture. Operating system integrates features
of AI technology like Siri, Google Assistant, and Alexa and became more powerful and efficient in many
way. These AI features with operating system create a entire new feature like voice commands, predictive
text, and personalized recommendations.
Advantages of Operating System
Operating System manages external and internal devices for example, printers, scanners, and
other.
Operating System provides interfaces and drivers for proper communication between system and
hardware devices.
Allows multiple applications to run simultaneously.
Manages the execution of processes, ensuring that the system remains responsive.
Organizes and manages files on storage devices.
Operating system allocates resources to various applications and ensures their efficient utilization.
Disadvantages of Operating System
If an error occurred in your operating system, then there may be a chance that your data may not
be recovered therefore always have a backup of your data.
Threats and viruses can attack our operating system at any time, making it challenging for the OS
to keep the system protected from these dangers.
For learning about new operating system can be a time-consuming and challenging, Specially for
those who using particular Operating system for example switching from Windows OS to Linux
is difficult.
Keeping an operating system up-to-date requires regular maintenance, which can be time-
consuming.
Operating systems consume system resources, including CPU, memory, and storage, which can
affect the performance of other applications.
How has the development of computer hardware been impacted by the evolution of operating systems?
The design and advancement of computer hardware have been significantly influenced by the development of
operating systems. by time hardware producers added new features and capabilities to their products as operating
systems improved in order to better support the functionality offered by the operating systems after a long variation
of time. Like for instance, basically the development of memory management units (MMUs) in hardware to handle
memory addressing and protection followed the introduction of virtual memory in operating systems. Similarly,
the demand for operating system multitasking and multiprocessing support prompted the creation of more potent
and effective processors and other hardware components.
How has the development of distributed systems impacted how operating systems have changed over time?
Operating systems have been significantly impacted by the rise of distributed systems, such as client-server
architectures and cloud computing. To support network communication, distributed file systems, and resource
sharing across multiple machines, operating systems had to develop. Distributed operating systems also developed
to offer scalability, fault tolerance, and coordination in distributed environments. These modifications improved
the ability to manage resources across interconnected systems by advancing networking protocols, remote
procedure calls, and distributed file systems.
Fig. Layered OS
The extended machine provides operations like context save, dispatching, swapping, and I/O initiation. The
operating system layer is located on top of the extended machine layer. This arrangement considerably simplifies
the coding and testing of OS modules by separating the algorithm of a function from the implementation of its
primitive operations. It is now easier to test, debug, and modify an OS module than in a monolithic OS. We say
that the lower layer provides an abstraction that is the extended machine. We call the operating system layer the
top layer of the OS.
Purposes and Tasks of Operating Systems
Several tasks are performed by the Operating Systems and it also helps in serving a lot of purposes which are
mentioned below. We will see how Operating System helps us in serving in a better way with the help of the task
performed by it.
Purposes of an Operating System
It controls the allocation and use of the computing System’s resources among the various user and tasks.
It provides an interface between the computer hardware and the programmer that simplifies and makes it
feasible for coding and debugging of application programs.
Tasks of an Operating System
1. Provides the facilities to create and modify programs and data files using an editor.
2. Access to the compiler for translating the user program from high-level language to machine language.
3. Provide a loader program to move the compiled program code to the computer’s memory for execution.
4. Provide routines that handle the details of I/O programming.
I/O System Management
The module that keeps track of the status of devices is called the I/O traffic controller. Each I/O device has a
device handler that resides in a separate process associated with that device.
The I/O subsystem consists of
A memory Management component that includes buffering caching and spooling.
A general device driver interface.
Drivers for Specific Hardware Devices
Below mentioned are the drivers which are required for a specific Hardware Device. Here we discussed
Assemblers, compilers, and interpreters, loaders.
Assembler
The input to an assembler is an assembly language program. The output is an object program plus information that
enables the loader to prepare the object program for execution. At one time, the computer programmer had at his
disposal a basic machine that interpreted, through hardware, certain fundamental instructions. He would program
this computer by writing a series of ones and Zeros (Machine language) and placing them into the memory of the
machine. Examples of assembly languages include
Compiler and Interpreter
The High-level languages – examples are C, C++, Java, Python, etc (around 300+ famous high-level languages)
are processed by compilers and interpreters. A compiler is a program that accepts a source program in a “high-
level language “and produces machine code in one go. Some of the compiled languages are FORTRAN, COBOL,
C, C++, Rust, and Go. An interpreter is a program that does the same thing but converts high-level code to machine
code line-by-line and not all at once. Examples of interpreted languages are
Python
Perl
Ruby
Loader
A Loader is a routine that loads an object program and prepares it for execution. There are various loading schemes:
absolute, relocating, and direct-linking. In general, the loader must load, relocate and link the object program. The
loader is a program that places programs into memory and prepares them for execution. In a simple loading scheme,
the assembler outputs the machine language translation of a program on a secondary device and a loader places it
in the core. The loader places into memory the machine language version of the user’s program and transfers
control to it. Since the loader program is much smaller than the assembler, those make more core available to the
user’s program.
Components of an Operating Systems
There are two basic components of an Operating System.
Shell
Kernel
Shell
Shell is the outermost layer of the Operating System and it handles the interaction with the user. The main task of
the Shell is the management of interaction between the User and OS. Shell provides better communication with
the user and the Operating System Shell does it by giving proper input to the user it also interprets input for the
OS and handles the output from the OS. It works as a way of communication between the User and the OS.
Kernel
The kernel is one of the components of the Operating System which works as a core component. The rest of the
components depends on Kernel for the supply of the important services that are provided by the Operating System.
The kernel is the primary interface between the Operating system and Hardware.
Functions of Kernel
The following functions are to be performed by the Kernel.
It helps in controlling the System Calls.
It helps in I/O Management.
It helps in the management of applications, memory, etc.
Types of Kernel
There are four types of Kernel that are mentioned below.
Monolithic Kernel
Microkernel
Hybrid Kernel
Exokernel
Less amount of data is managed in 32-Bit Operating A large amount of data can be stored in 64-Bit
System as compared to 64-Bit Os. Operating System.
32-Bit Operating System can address 2^32 bytes of 64-Bit Operating System can address 2^64 bytes of
RAM. RAM.
Can run 32-bit and 16-bit Can run 32-bit and 64-bit
Compatibility
applications applications
Address Space Uses 32-bit address space Uses 64-bit address space
Gamers can easily play High graphical games like Modern Warfare, and GTA V, or use high-end
software like Photoshop or CAD which takes a lot of memory since it makes multi-tasking with big
software, easy and efficient for users. However, upgrading the video card instead of getting a 64-bit
processor would be more beneficial.
Note:
A computer with a 64-bit processor can have a 64-bit or 32-bit version of an operating system installed.
However, with a 32-bit operating system, the 64-bit processor would not run at its full capability.
On a computer with a 64-bit processor, we can’t run a 16-bit legacy program. Many 32-bit programs will
work with a 64-bit processor and operating system, but some older 32-bit programs may not function
properly, or at all, due to limited or no compatibility.
This type of operating system does not interact with the computer directly. There is an operator which takes
similar jobs having the same requirements and groups them into batches. It is the responsibility of the operator
to sort jobs with similar needs. Batch Operating System is designed to manage and execute a large number of
jobs efficiently by processing them in groups.
Batch Operating System
CPU is not used efficiently. When the current process is doing IO, CPU is free and could be utilized by
other processes waiting.
The other jobs will have to wait for an unknown time if any job fails.
In batch operating system, average response time increases as all processes are processed one by one.
Multiprogramming Operating Systems can be simply illustrated as more than one program is present in the
main memory and any one of them can be kept in execution. This is basically used for better utilization of
resources.
MultiProgramming
Advantages of Multi-Programming Operating System
It is a type of Multiprogramming system with every process running in round robin manner. Each task is given
some time to execute so that all the tasks work smoothly. Each user gets the time of the CPU as they use a
single system. These systems are also known as Multitasking Systems. The task can be from a single user or
different users also. The time that each task gets to execute is called quantum. After this time interval is over
OS switches over to the next task.
Advantages of Time-Sharing OS
Resource Sharing: Time-sharing systems allow multiple users to share hardware resources such as the
CPU, memory, and peripherals, reducing the cost of hardware and increasing efficiency.
Improved Productivity: Time-sharing allows users to work concurrently, thereby reducing the waiting
time for their turn to use the computer. This increased productivity translates to more work getting
done in less time.
Improved User Experience: Time-sharing provides an interactive environment that allows users to
communicate with the computer in real time, providing a better user experience than batch processing.
Disadvantages of Time-Sharing OS
Reliability problem.
One must have to take care of the security and integrity of user programs and data.
Complexity: Time-sharing systems are complex and require advanced software to manage multiple users
simultaneously. This complexity increases the chance of bugs and errors.
Security Risks: With multiple users sharing resources, the risk of security breaches increases. Time-
sharing systems require careful management of user access, authentication, and authorization to ensure
the security of data and software.
IBM VM/CMS : IBM VM/CMS is a time-sharing operating system that was first introduced in 1972. It is
still in use today, providing a virtual machine environment that allows multiple users to run their own
instances of operating systems and applications.
TSO (Time Sharing Option) : TSO is a time-sharing operating system that was first introduced in the 1960s
by IBM for the IBM System/360 mainframe computer. It allowed multiple users to access the same
computer simultaneously, running their own applications.
Windows Terminal Services : Windows Terminal Services is a time-sharing operating system that allows
multiple users to access a Windows server remotely. Users can run their own applications and access
shared resources, such as printers and network storage, in real-time.
Multi-Processing Operating System is a type of Operating System in which more than one CPU is used for the
execution of resources. It betters the throughput of the System.
As it has several processors, so, if one processor fails, we can proceed with another processor.
4. Multi User Operating Systems
These systems allow multiple users to be active at the same time. These system can be either multiprocessor or
single processor with interleaving.
Time-Sharing OS
These types of operating system is a recent advancement in the world of computer technology and are being
widely accepted all over the world and, that too, at a great pace. Various autonomous interconnected computers
communicate with each other using a shared communication network. Independent systems possess their own
memory unit and CPU. These are referred to as loosely coupled systems or distributed systems . These systems’
processors differ in size and function. The major benefit of working with these types of the operating system is
that it is always possible that one user can access the files or software which are not actually present on his
system but some other system connected within this network i.e., remote access is enabled within the devices
connected in that network.
Distributed OS
Advantages of Distributed Operating System
Failure of one will not affect the other network communication, as all systems are independent of each
other.
Since resources are being shared, computation is highly fast and durable.
These systems are easily scalable as many systems can be easily added to the network.
These types of systems are not readily available as they are very expensive. Not only that the underlying
software is highly complex and not understood well yet.
Networking causes delays in the transfer of data between nodes of a distributed system. Such delays
may lead to an inconsistent view of data located in different nodes, and make it difficult to know the
chronological order in which events occurred in the system.
Control functions like scheduling, resource allocation, and deadlock detection have to be performed in
several nodes to achieve computation speedup and provide reliable operation when computers or
networking components fail.
Messages exchanged by processes present in different nodes may travel over public networks and pass
through computer systems that are not controlled by the distributed operating system. An intruder may
exploit this feature to tamper with messages, or create fake messages to fool the authentication
procedure and masquerade as a user of the system.
These systems run on a server and provide the capability to manage data, users, groups, security, applications,
and other networking functions. These types of operating systems allow shared access to files, printers, security,
applications, and other networking functions over a small private network. One more important aspect of
Network Operating Systems is that all the users are well aware of the underlying configuration, of all other users
within the network, their individual connections, etc. and that’s why these computers are popularly known
as tightly coupled systems .
Network Operating System
New technologies and hardware up-gradation are easily integrated into the system.
Server access is possible remotely from different locations and types of systems.
Examples of Network Operating Systems are Microsoft Windows Server 2003, Microsoft Windows Server
2008, UNIX, Linux, Mac OS X, Novell NetWare, BSD, etc.
These types of OSs serve real-time systems. The time interval required to process and respond to inputs is very
small. This time interval is called response time.Real-time systems are used when there are time requirements
that are very strict like missile systems, air traffic control systems, robots, etc.
Hard Real-Time Systems: Hard Real-Time OSs are meant for applications where time constraints are
very strict and even the shortest possible delay is not acceptable. These systems are built for saving life
like automatic parachutes or airbags which are required to be readily available in case of an accident.
Virtual memory is rarely found in these systems.
Soft Real-Time Systems: These OSs are for applications where time-constraint is less strict.
Real-Time Operating System
Advantages of RTOS
Maximum Consumption: Maximum utilization of devices and systems, thus more output from all the
resources.
Task Shifting: The time assigned for shifting tasks in these systems is very less. For example, in older
systems, it takes about 10 microseconds in shifting from one task to another, and in the latest systems,
it takes 3 microseconds.
Focus on Application: Focus on running applications and less importance on applications that are in the
queue.
Real-time operating system in the embedded system: Since the size of programs is small, RTOS can
also be used in embedded systems like in transport and others.
Disadvantages of RTOS
Limited Tasks: Very few tasks run at the same time and their concentration is very less on a few
applications to avoid errors.
Use heavy system resources: Sometimes the system resources are not so good and they are expensive
as well.
Complex Algorithms: The algorithms are very complex and difficult for the designer to write on.
Device driver and interrupt signals: It needs specific device drivers and interrupts signal to respond
earliest to interrupts.
Thread Priority: It is not good to set thread priority as these systems are very less prone to switching
tasks.
Examples of Real-Time Operating Systems are Scientific experiments, medical imaging systems, industrial
control systems, weapon systems, robots, air traffic control systems, etc.
These operating systems are mainly for mobile devices. Examples of such operating systems are Android and
iOS.
An Operating System acts as a communication interface between the user and computer hardware. Its purpose
is to provide a platform on which a user can execute programs conveniently and efficiently. An operating system
is software that manages the allocation of Computer Hardware. The coordination of the hardware must be
appropriate to ensure the computer system’s correct operation and to prevent user programs from interfering
with it. The main goal of the Operating System is to make the computer environment more convenient to use
and the Secondary goal is to use the resources most efficiently. In this article we will see functions of operating
system in detail.
Operating System is used as a communication channel between the Computer hardware and the user. It works
as an intermediate between System Hardware and End-User. Operating System handles the following
responsibilities:
Memory Management
The operating system manages the Primary Memory or Main Memory. Main memory is made up of a large array
of bytes or words where each byte or word is assigned a certain address. Main memory is fast storage and it can
be accessed directly by the CPU. For a program to be executed, it should be first loaded in the main memory. An
operating system manages the allocation and deallocation of memory to various processes and ensures that the
other process does not consume the memory allocated to one process. An Operating System performs the
following activities for Memory Management:
It keeps track of primary memory, i.e., which bytes of memory are used by which user program. The
memory addresses that have already been allocated and the memory addresses of the memory that
has not yet been used.
In multiprogramming, the OS decides the order in which processes are granted memory access, and for
how long.
It Allocates the memory to a process when the process requests it and deallocates the memory when
the process has terminated or is performing an I/O operation.
Memory Management
Processor Management
In a multi-programming environment, the OS decides the order in which processes have access to the processor,
and how much processing time each process has. This function of OS is called Process Scheduling. An Operating
System performs the following activities for Processor Management.
An operating system manages the processor’s work by allocating various jobs to it and ensuring that each process
receives enough time from the processor to function properly.
Keeps track of the status of processes. The program which performs this task is known as a traffic controller.
Allocates the CPU that is a processor to a process. De-allocates processor when a process is no longer required.
Process management
Device Management
An OS manages device communication via its respective drivers. It performs the following activities for device
management.
Keeps track of all devices connected to the system. Designates a program responsible for every device
known as the Input/Output controller.
Decide which process gets access to a certain device and for how long.
Allocates devices effectively and efficiently. Deallocates devices when they are no longer required.
There are various input and output devices. An OS controls the working of these input-output devices.
It receives the requests from these devices, performs a specific task, and communicates back to the
requesting process.
File Management
A file system is organized into directories for efficient or easy navigation and usage. These directories may contain
other directories and other files. An Operating System carries out the following file management activities. It
keeps track of where information is stored, user access settings, the status of every file, and more. These facilities
are collectively known as the file system. An OS keeps track of information regarding the creation, deletion,
transfer, copy, and storage of files in an organized way. It also maintains the integrity of the data stored in these
files, including the file directory structure, by protecting against unauthorized access.
File Management
I/O Management
I/O management is the important function of operating system refers to how the OS
handles input and output operations between the computer and external devices, such as keyboards, mice,
printers, hard drives, and monitors.
The user interacts with the computer system through the operating system. Hence OS acts as an interface
between the user and the computer hardware. This user interface is offered through a set of commands or a
graphical user interface (GUI). Through this interface, the user makes interacts with the applications and the
machine hardware.
Command interpreter
The process of starting or restarting the computer is known as booting. If the computer is switched off completely
and if turned on then it is called cold booting. Warm booting is a process of using the operating system to restart
the computer.
Security
The operating system uses password protection to protect user data and similar other techniques. it also prevents
unauthorized access to programs and user data. The operating system provides various techniques which assure
the integrity and confidentiality of user data. The following security measures are used to protect user data:
Operating systems play a pivotal role in controlling and optimizing system performance. They act as
intermediaries between hardware and software, ensuring that computing resources are efficiently utilized. One
fundamental aspect is resource allocation, where the OS allocates CPU time, memory, and I/O devices to
different processes, striving to provide fair and optimal resource utilization. Process scheduling, a critical
function, helps decide which processes or threads should run when preventing any single task from monopolizing
the CPU and enabling effective multitasking.
Job Accounting
The operating system Keeps track of time and resources used by various tasks and users, this information can be
used to track resource usage for a particular user or group of users. In a multitasking OS where multiple programs
run simultaneously, the OS determines which applications should run in which order and how time should be
allocated to each application.
Error-Detecting Aids
The operating system constantly monitors the system to detect errors and avoid malfunctioning computer
systems. From time to time, the operating system checks the system for any external threat or malicious software
activity. It also checks the hardware for any type of damage. This process displays several alerts to the user so
that the appropriate action can be taken against any damage caused to the system.
Operating systems also coordinate and assign interpreters, compilers, assemblers, and other software to the
various users of the computer systems. In simpler terms, think of the operating system as the traffic cop of your
computer. It directs and manages how different software programs can share your computer’s resources without
causing chaos. It ensures that when you want to use a program, it runs smoothly without crashing or causing
problems for others. So, it’s like the friendly officer ensuring a smooth flow of traffic on a busy road, making sure
everyone gets where they need to go without any accidents or jams.
The management of various peripheral devices such as the mouse, keyboard, and printer is carried out by the
operating system. Today most operating systems are plug-and-play. These operating systems automatically
recognize and configure the devices with no user interference.
Network Management
Network Communication: Think of them as traffic cops for your internet traffic. Operating systems help
computers talk to each other and the internet. They manage how data is packaged and sent over the
network, making sure it arrives safely and in the right order.
Settings and Monitoring: Think of them as the settings and security guard for your internet connection.
They also let you set up your network connections, like Wi-Fi or Ethernet, and keep an eye on how your
network is doing. They make sure your computer is using the network efficiently and securely, like
adjusting the speed of your internet or protecting your computer from online threats.
The Operating System provides certain services to the users which can be listed in the following manner:
User Interface: Almost all operating systems have a user interface (UI). This interface can take several
forms. One is a command-line interface(CLI), which uses text commands and a method for entering them
(say, a keyboard for typing in commands in a specific format with specific options). Another is a batch
interface, in which commands and directives to control those commands are entered into files, and those
files are executed. Most commonly, a graphical user interface (GUI) is used. the interface is a window
system with a pointing device to direct I/O, choose from menus, and make selections and a keyboard to
enter text.
Program Execution: The Operating System is responsible for the execution of all types of programs
whether it be user programs or system programs. The Operating System utilizes various resources
available for the efficient running of all types of functionalities.
Handling Input/Output Operations: The Operating System is responsible for handling all sorts of inputs,
i.e., from the keyboard, mouse, desktop, etc. The Operating System does all interfacing most
appropriately regarding all kinds of Inputs and Outputs.
For example, there is a difference between all types of peripheral devices such as mice or keyboards, the
Operating System is responsible for handling data between them.
Manipulation of File System: The Operating System is responsible for making decisions regarding the
storage of all types of data or files, i.e., floppy disk/hard disk/pen drive, etc. The Operating System
decides how the data should be manipulated and stored.
Resource Allocation: The Operating System ensures the proper use of all the resources available by
deciding which resource to be used by whom for how much time. All the decisions are taken by the
Operating System.
Accounting: The Operating System tracks an account of all the functionalities taking place in the
computer system at a time. All the details such as the types of errors that occurred are recorded by the
Operating System.
Information and Resource Protection: The Operating System is responsible for using all the information
and resources available on the machine in the most protected way. The Operating System must foil an
attempt from any external resource to hamper any sort of data or information.
Communication: The operating system implements communication between one process to another
process to exchange information. Such communication may occur between processes that are executing
on the same computer or between processes that are executing on different computer systems tied
together by a computer network.
System Services: The operating system provides various system services, such as printing, time and date
management, and event logging.
Error Detection: The operating system needs to be detecting and correcting errors constantly. Errors
may occur in the CPU and memory hardware ( for eg. a memory error or a power failure), in I/O devices
(such as a parity error on disk, a connection failure on a network, or a lack of paper in the printer), and
in the user program ( an arithmetic overflow, an attempt to access an illegal memory location or a too-
great use of CPU time). For each type of error, the operating system should take the appropriate action
to ensure correct and consistent computing.
All these services are ensured by the Operating System for the convenience of the users to make the
programming task easier. All different kinds of Operating Systems more or less provide the same services.
Virtualization: Operating systems can provide Virtualization capabilities, allowing multiple operating
systems or instances of an operating system to run on a single physical machine. This can improve
resource utilization and provide isolation between different operating systems or applications.
Networking: Operating systems provide networking capabilities, allowing the computer system to
connect to other systems and devices over a network. This can include features such as network
protocols, network interfaces, and network security.
Scheduling: Operating systems provide scheduling algorithms that determine the order in which tasks
are executed on the system. These algorithms prioritize tasks based on their resource requirements and
other factors to optimize system performance.
Backup and Recovery: Operating systems provide backup and recovery mechanisms to protect data in
the event of system failure or data loss.
Debugging: Operating systems provide debugging tools that allow developers to identify and fix
software bugs and other issues in the system.
A computer without a program running is just an inert hunk of electronics. The first thing a computer has to do
when it is turned on is to start up a special program called an operating system. The operating system’s job is to
help other computer programs work by handling the messy details of controlling the computer’s hardware.
1. The power supply sends electricity to the components of the computer, such as the motherboard, hard
drive, and fans.
2. The BIOS (basic input/output system) or UEFI initializes and performs a power-on self-test (POST), which
checks the basic hardware components to ensure they are working properly. If any issues are detected,
error messages may be displayed.
3. The operating system (OS), such as Windows or macOS, is loaded from the hard drive or another storage
device into the computer’s RAM (random access memory).
4. The OS then initializes its own components and drivers and presents the login screen or desktop
environment to the user.
The BIOS chip tells it to look in a fixed place, usually on the lowest-numbered hard disk (the boot disk) for a
special program called a boot loader (under Linux the boot loader is called Grub or LILO). The boot loader is pulled
into memory and started. The bootloader’s job is to start the real operating system.
Functions of BIOS
1. POST (Power On Self Test): The Power On Self Test happens each time you turn your computer on. It sounds
complicated and that’s because it kind of is. Your computer does so much when it’s turned on and this is just part
of that.
It is an important process to ensure that all the devices operate smoothly without any conflicts. BIOSes
following ACPI create tables describing the devices in the computer.
The POST first checks the bios and then tests the CMOS RAM.
If there is no problem with this then POST continues to check the CPU, hardware devices such as the
Video Card, and the secondary storage devices such as the Hard Drive, Floppy Drives, Zip Drive, or
CD/DVD Drives.
If some errors are found then an error message is displayed on the screen or a number of beeps are
heard.
2. Master Boot Record: The Master Boot Record (MBR) is a special boot sector at the beginning of the disk. The
MBR contains the code that loads the rest of OS, known as bootloader. This complicated process (called the
Boot Process) starts with the POST (Power On Self Test) and ends when the Bios searches for the MBR on the
Hard Drive, which is generally located in the first sector, first head, first cylinder (cylinder 0, head 0, sector 1).
A typical structure looks like this:
The bootstrap loader is stored in the computer’s EPROM, ROM, or another non-volatile memory. When the
computer is turned on or restarted, it first performs the power-on-self-test, also known as POST. If the POST is
successful and no issues are found, the bootstrap loader will load the operating system for the computer into
memory. The computer will then be able to quickly access, load, and run the operating system.
3. init: init is the last step of the kernel boot sequence. It looks for the file /etc/inittab to see if there is an entry
for initdefault. It is used to determine the initial run level of the system. A run-level is used to decide the initial
state of the operating system.
Some of the run levels are:
The above design of init is called SysV- pronounced as System five. Several other implementations of init have
been written now. Some of the popular implementations are systemd and upstart. Upstart is being used by
ubuntu since 2006. More details of the upstart can be found here.
The next step of init is to start up various daemons that support networking and other services. X server daemon
is one of the most important daemons. It manages the display, keyboard, and mouse. When X server daemon is
started you see a Graphical Interface and a login screen is displayed.
4. System Configuration:
The BIOS allows the user to configure various system settings, such as:
1. Boot order: This determines the order in which the computer checks for bootable devices. For example,
if the boot order is set to “hard drive” first, the computer will try to boot from the hard drive before
checking other devices such as a CD/DVD drive or a USB drive.
2. Time and date: The BIOS stores the time and date information, which can be set and adjusted by the
user. This information is used by the operating system and various applications.
3. Hardware settings: The BIOS provides options to configure various hardware settings such as CPU
voltage, clock speed, and memory timings. These settings can be used to optimize system performance,
but should only be changed by advanced users with the proper knowledge.
5. Security:
The BIOS can also provide security features such as:
1. Password protection: The BIOS can be set to require a password to access certain features or to prevent
unauthorized booting of the computer. This can be useful in preventing unauthorized access to sensitive
data.
2. Secure boot: Secure boot is a feature that ensures that only trusted operating system boot loaders,
drivers, and firmware are loaded during the boot process. This helps to prevent malware and other
unauthorized software from running on the system.
3. TPM (Trusted Platform Module): Some modern motherboards have a built-in TPM that provides
hardware-based security features such as encryption, digital certificates, and secure key storage. This
can help to protect sensitive data and prevent unauthorized access to the system.
A kernel is the core part of an operating system. It acts as a bridge between software applications and the
hardware of a computer.
The kernel manages system resources, such as the CPU, memory, and devices, ensuring everything
works together smoothly and efficiently.
It handles tasks like running programs, accessing files, and connecting to devices like printers and
keyboards.
An Operating System includes the kernel as its core, but also provides a user interface, file system
management, network services, and various utility applications that allow users to interact with the
system
Types of Kernel
The kernel manages the system’s resources and facilitates communication between hardware and software
components. These kernels are of different types let’s discuss each type along with its advantages and
disadvantages:
1. Monolithic Kernel
It is one of the types of kernel where all operating system services operate in kernel space. It has dependencies
between systems components. It has huge lines of code which is complex.
Example:
Advantages
Efficiency: Monolithic kernels are generally faster than other types of kernels because they don’t have
to switch between user and kernel modes for every system call, which can cause overhead.
Tight Integration: Since all the operating system services are running in kernel space, they can
communicate more efficiently with each other, making it easier to implement complex functionalities
and optimizations.
Simplicity: Monolithic kernels are simpler to design, implement, and debug than other types of kernels
because they have a unified structure that makes it easier to manage the code.
Lower latency: Monolithic kernels have lower latency than other types of kernels because system calls
and interrupts can be handled directly by the kernel.
Disadvantages
Stability Issues: Monolithic kernels can be less stable than other types of kernels because any bug or
security vulnerability in a kernel service can affect the entire system.
Security Vulnerabilities: Since all the operating system services are running in kernel space, any
security vulnerability in one of the services can compromise the entire system.
Maintenance Difficulties: Monolithic kernels can be more difficult to maintain than other types of
kernels because any change in one of the services can affect the entire system.
Limited Modularity: Monolithic kernels are less modular than other types of kernels because all the
operating system services are tightly integrated into the kernel space. This makes it harder to add or
remove functionality without affecting the entire system.
2. Micro Kernel
It is kernel types which has minimalist approach. It has virtual memory and thread scheduling. Micro Kernel is
more stable with less services in kernel space. It puts rest in user space. It is use in small os.
Example :
Advantages
Reliability: Microkernel architecture is designed to be more reliable than monolithic kernels. Since
most of the operating system services run outside the kernel space, any bug or security vulnerability in
a service won’t affect the entire system.
Flexibility : Microkernel architecture is more flexible than monolithic kernels because it allows different
operating system services to be added or removed without affecting the entire system.
Modularity: Microkernel architecture is more modular than monolithic kernels because each operating
system service runs independently of the others. This makes it easier to maintain and debug the
system.
Portability: Microkernel architecture is more portable than monolithic kernels because most of the
operating system services run outside the kernel space. This makes it easier to port the operating
system to different hardware architectures.
Disadvantages
Performance: Microkernel architecture can be slower than monolithic kernels because it requires more
context switches between user space and kernel space.
Complexity: Microkernel architecture can be more complex than monolithic kernels because it requires
more communication and synchronization mechanisms between the different operating system
services.
Development Difficulty: Developing operating systems based on microkernel architecture can be more
difficult than developing monolithic kernels because it requires more attention to detail in designing
the communication and synchronization mechanisms between the different services.
Higher Resource Usage: Microkernel architecture can use more system resources, such as memory and
CPU, than monolithic kernels because it requires more communication and synchronization
mechanisms between the different operating system services.
3. Hybrid Kernel
It is the combination of both monolithic kernel and microkernel. It has speed and design of monolithic kernel
and modularity and stability of microkernel.
Example :
Advantages
Performance: Hybrid kernels can offer better performance than microkernels because they reduce the
number of context switches required between user space and kernel space.
Reliability: Hybrid kernels can offer better reliability than monolithic kernels because they
isolate drivers and other kernel components in separate protection domains.
Flexibility: Hybrid kernels can offer better flexibility than monolithic kernels because they allow
different operating system services to be added or removed without affecting the entire system.
Compatibility: Hybrid kernels can be more compatible than microkernels because they can support a
wider range of device drivers.
Disadvantages
Complexity: Hybrid kernels can be more complex than monolithic kernels because they include both
monolithic and microkernel components, which can make the design and implementation more
difficult.
Security: Hybrid kernels can be less secure than microkernels because they have a larger attack surface
due to the inclusion of monolithic components.
Maintenance: Hybrid kernels can be more difficult to maintain than microkernels because they have a
more complex design and implementation.
Resource Usage: Hybrid kernels can use more system resources than microkernels because they
include both monolithic and microkernel components.
4. Exo Kernel
It is the type of kernel which follows end-to-end principle. It has fewest hardware abstractions as possible. It
allocates physical resources to applications.
Example :
Nemesis, ExOS etc.
Advantages
Flexibility: Exokernels offer the highest level of flexibility, allowing developers to customize and
optimize the operating system for their specific application needs.
Performance: Exokernels are designed to provide better performance than traditional kernels because
they eliminate unnecessary abstractions and allow applications to directly access hardware resources.
Security: Exokernels provide better security than traditional kernels because they allow for fine-grained
control over the allocation of system resources, such as memory and CPU time.
Modularity: Exokernels are highly modular, allowing for the easy addition or removal of operating
system services.
Disadvantages
Complexity: Exokernels can be more complex to develop than traditional kernels because they require
greater attention to detail and careful consideration of system resource allocation.
Development Difficulty: Developing applications for exokernels can be more difficult than for
traditional kernels because applications must be written to directly access hardware resources.
Limited Support: Exokernels are still an emerging technology and may not have the same level of
support and resources as traditional kernels.
Debugging Difficulty: Debugging applications and operating system services on exokernels can be more
difficult than on traditional kernels because of the direct access to hardware resources.
5. Nano Kernel
It is the type of kernel that offers hardware abstraction but without system services. Micro Kernel also does not
have system services therefore the Micro Kernel and Nano Kernel have become analogous.
Example :
EROS etc.
Advantages
Small Size: Nanokernels are designed to be extremely small, providing only the most essential functions
needed to run the system. This can make them more efficient and faster than other kernel types.
High Modularity: Nanokernels are highly modular, allowing for the easy addition or removal of
operating system services, making them more flexible and customizable than traditional monolithic
kernels.
Security: Nanokernels provide better security than traditional kernels because they have a smaller
attack surface and a reduced risk of errors or bugs in the code.
Portability: Nanokernels are designed to be highly portable, allowing them to run on a wide range of
hardware architectures.
Disadvantages
Limited Functionality: Nanokernels provide only the most essential functions, making them unsuitable
for more complex applications that require a broader range of services.
Complexity: Because nanokernels provide only essential functionality, they can be more complex to
develop and maintain than other kernel types.
Performance: While nanokernels are designed for efficiency, their minimalist approach may not be
able to provide the same level of performance as other kernel types in certain situations.
Compatibility: Because of their minimalist design, nanokernels may not be compatible with all
hardware and software configurations, limiting their practical use in certain contexts.
Functions of Kernel
The kernel is responsible for various critical functions that ensure the smooth operation of the computer
system. These functions include:
1. Process Management
2. Memory Management
3. Device Management
5. Resource Management
7. Inter-Process Communication
Working of Kernel
A kernel loads first into memory when an operating system is loaded and remains in memory until the
operating system is shut down again. It is responsible for various tasks such as disk management , task
management, and memory management .
The kernel has a process table that keeps track of all active processes
The process table contains a per-process region table whose entry points to entries in the region table.
The kernel loads an executable file into memory during the ‘exec’ system call’.
It decides which process should be allocated to the processor to execute and which process should be
kept in the main memory to execute. It basically acts as an interface between user applications and
hardware. The major aim of the kernel is to manage communication between software i.e. user-level
applications and hardware i.e., CPU and disk memory.
Objectives of Kernel
A system call is a programmatic way in which a computer program requests a service from the kernel of the
operating system it is executed on. A system call is a way for programs to interact with the operating system. A
computer program makes a system call when it requests the operating system’s kernel. System call provides the
services of the operating system to the user programs via the Application Program Interface(API). System calls
are the only entry points into the kernel system and are executed in kernel mode.
A user program can interact with the operating system using a system call. A number of services are
requested by the program, and the OS responds by launching a number of systems calls to fulfill the
request.
A system call can be written in high-level languages like C or Pascal or in assembly language. If a high-
level language is used, the operating system may directly invoke system calls, which are predefined
functions.
A system call is initiated by the program executing a specific instruction, which triggers a switch to kernel
mode, allowing the program to request a service from the OS. The OS then handles the request, performs
the necessary operations, and returns the result back to the program.
System calls are essential for the proper functioning of an operating system, as they provide a
standardized way for programs to access system resources. Without system calls, each program would
need to implement its methods for accessing hardware and system services, leading to inconsistent and
error-prone behavior.
Interface: System calls provide a well-defined interface between user programs and the operating
system. Programs make requests by calling specific functions, and the operating system responds by
executing the requested service and returning a result.
Protection: System calls are used to access privileged operations that are not available to normal user
programs. The operating system uses this privilege to protect the system from malicious or unauthorized
access.
Kernel Mode: When a system call is made, the program is temporarily switched from user mode
to kernel mode. In kernel mode, the program has access to all system resources, including hardware,
memory, and other processes.
Context Switching: A system call requires a context switch, which involves saving the state of the current
process and switching to the kernel mode to execute the requested service. This can introduce overhead,
which can impact system performance.
Error Handling: System calls can return error codes to indicate problems with the requested service.
Programs must check for these errors and handle them appropriately.
Synchronization: System calls can be used to synchronize access to shared resources, such as files or
network connections. The operating system provides synchronization mechanisms, such as locks
or semaphores, to ensure that multiple programs can access these resources safely.
Users need special resources: Sometimes programs need to do some special things that can’t be done
without the permission of the OS like reading from a file, writing to a file, getting any information from
the hardware, or requesting a space in memory.
The program makes a system call request: There are special predefined instructions to make a request
to the operating system. These instructions are nothing but just a “system call”. The program uses these
system calls in its code when needed.
Operating system sees the system call: When the OS sees the system call then it recognizes that the
program needs help at this time so it temporarily stops the program execution and gives all the control
to a special part of itself called ‘Kernel’. Now ‘Kernel’ solves the need of the program.
The operating system performs the operations: Now the operating system performs the operation that
is requested by the program. Example: reading content from a file etc.
Operating system give control back to the program : After performing the special operation, OS give
control back to the program for further execution of program.
System calls are interfaces provisioned by the operating system to allow user-level applications to interact with
low-level hardware components & make use of all the services provided by the kernel, which is a core component
and the heart of an operating system that manages all the hardware and the services provided by the OS.
These system calls are essential for every process to interact with the kernel and properly use the services
provided by it. System calls are an interface between a process and the operating system. And they're the only
way to switch from user mode to kernel mode.
Services provided by an OS are typically related to any kind of operation that a user program can perform like
creation, termination, forking, moving, communication, etc. Similar types of operations are grouped into one
single system call category. System calls are classified into the following categories:
These system calls are made while working with files in OS, File manipulation operations such as creation,
deletion, termination etc.
open(): Opens a file for reading or writing. A file could be of any type like text file, audio file etc.
read(): Reads data from a file. Just after the file is opened through open() system call, then if some
process want to read the data from a file, then it will make a read() system call.
write(): Writes data to a file. Wheneve the user makes any kind of modification in a file and saves it,
that's when this is called.
seek(): Moves the file pointer within a file. This call is typically made when we the user tries to read the
data from a specific position in a file. For example, read from line - 47. Than the file pointer will move
from line 1 or wherever it was previously to line-47.
Algorithm for Reading a File
algorithm read
input: user file descriptor, address of buffer in user process, number of bytes to read
set parameters in u area for user address, byte count, I/O to user;
lock inode;
break;
read block (algorithm breada if with read ahead, algorithm bread otherwise);
update u area fields for file byte offset, read count, address to write into user space;
release buffer;
unlock inode;
2. Process Control
These types of system calls deal with process creation, process termination, process allocation, deallocation etc.
Basically manages all the process that are a part of OS.
fork(): Creates a new process (child) by duplicating the current process (parent). This call is made when
a process makes a copy of itself and the parent process is halted temporarily until the child process
finishes its execution.
exec(): Loads and runs a new program in the current process and replaces the current process with a
new process. All the data such as stack, register, heap memory everything is replaced by a new process
and this is known as overlay. For example, when you execute a java byte code using command - java
"filename". Then in the background, exec() call will be made to execute the java file and JVM will also be
executed.
wait(): The primary purpose of this call is to ensure that the parent process doesn't proceed further with
its execution until all its child processes have finished their execution. This call is made when one or more
child processes are forked.
kill(): This call sends a signal to a specific process and has various purpose including - requesting it to quit
voluntarily, or force quit, or reload configuration.
3. Memory Management
These types of system calls deals with memory allocation, deallocation & dynamically changing the size of a
memory allocated to a process. In short, the overall management of memory is done by making these system
calls.
brk(): Changes the data segment size for a process in HEAP Memory. It takes an address as argument to
define the end of the heap and explicitly sets the size of HEAP.
sbrk(): This call is also for memory management in heap, it also takes an argument as an integer (+ve or
-ve) specifying whether to increase or decrease the size respectively.
mmap(): Memory Map - It basically maps a file or device into main memory and further into a process's
address space for performing operations. And any changes made in the content of a file will be reflected
in the actual file.
munmap(): Unmaps a memory-mapped file from a process's address space and out of main memory
mlock() and unlock(): memory lock defines a mechanism through which certain pages stay in memory
and are not swapped out to the swap space in the disk. This could be done to avoid page faults. Memory
unlock is the opposite of lock, it releases the lock previously acquired on pages.
When two or more process are required to communicate, then various IPC mechanism are used by the OS which
involves making numerous system calls. Some of them are :
pipe(): Creates a unidirectional communication channel between processes. For example, a parent
process may communicate to its child process through a pipe making a parent process as input source of
its child process.
socket(): Creates a network socket for communication. Processes in same or other networks can
communicate through this socket, provided that they have necessary network permissions granted.
shmget(): It is short for - 'shared-memory-get'. It allows one or more processes to share a portion of
memory and achieve interprocess communication.
semget(): It is short for - 'semaphore-get'. This call typically manages the coordination of multiple
processes while accessing a shared resource that is, the critical section.
msgget(): It is short for - 'message-get'. IPC mechanism has one of the fundamental concept called -
'message queue' which is a queue data structure inside memory through which various processes
communicate with each other. This message queue is allocated through this call allowing other processes
a structured way of communication for data exchange purpose.
5. Device Management
The device management system calls are used to interact with various peripherial devices attached to the PC or
even the management of the current device.
SetConsoleMode(): This call is made to set the mode of console (input or output). It allows a process to
control various console modes. In windows, it is used to control the behaviour of command line.
ReadConsole(): It allows us to read data from console screen (if any arguments are provided).
open(): This call is made whenever a device or a file is opened. A unique file descriptor is created to
maintain the control access to the opened file or device.
close(): This call is made when the system or the user closes the file or device.
Efficient Resource Management: System Calls help your computer manage its resources efficiently. They
allocate and manage memory so programs run smoothly without using up too many resources. This is
important for multitasking and overall performance.
Security and Isolation: System Calls ensure that one program cannot interfere with or access the
memory of another program. This enhances the security and stability of your device.
Multitasking Capabilities: System Calls support multitasking, allowing multiple programs to run
simultaneously. This improves productivity and makes it easy to switch between applications.
Enhanced Control: System Calls provide a high level of control over your device’s operations. They allow
you to start and stop processes, manage files, and perform various system-related tasks.
Input/Output (I/O) Operations: System Calls enable communication with input and output devices, such
as your keyboard, mouse, and screen. They ensure that these devices work effectively.
Networking and Communication: System Calls facilitate networking and communication between
different applications. They make it easy to transfer data over networks, browse the web, send emails,
and connect online.
What is The Purpose of System Calls in OS?
System Calls act as a bridge between an operating system (OS) and a running program. They are usually written
as assembly language instructions and are detailed in manuals for programmers working with assembly
language.
When a program running in user mode needs to access a resource, it makes a System Call. This request is sent to
the OS kernel to obtain the needed resource.
System calls for Windows and Unix come in many different forms. These are listed in the table below as follows:
CreateProcess() Fork()
Process Control ExitProcess() Exit()
WaitForSingleObject() Wait()
Open()
CreateFile()
Read()
File manipulation ReadFile()
Write()
WriteFile()
Close()
SetConsoleMode() Ioctl()
Device Management ReadConsole() Read()
WriteConsole() Write()
GetCurrentProcessID() Getpid()
Information Maintenance SetTimer() Alarm()
Sleep() Sleep()
CreatePipe() Pipe()
Communication
CreateFileMapping() Shmget()
Process Windows Unix
MapViewOfFile() Mmap()
SetFileSecurity() Chmod()
Protection InitializeSecurityDescriptor() Umask()
SetSecurityDescriptorgroup() Chown()
Open(): Accessing a file on a file system is possible with the open() system call. It gives the file resources it needs
and a handle the process can use. A file can be opened by multiple processes simultaneously or just one process.
Everything is based on the structure and file system.
Read(): Data from a file on the file system is retrieved using it. In general, it accepts three arguments:
A description of a file.
How many bytes should be read from the file Before reading, the file to be read could be identified by
its file descriptor and opened using the open() function.
Wait(): In some systems, a process might need to hold off until another process has finished running before
continuing. When a parent process creates a child process, the execution of the parent process is halted until the
child process is complete. The parent process is stopped using the wait() system call. The parent process regains
control once the child process has finished running.
Write(): Data from a user buffer is written using it to a device like a file. A program can produce data in one way
by using this system call. generally, there are three arguments:
A description of a file.
The amount of data that will be written from the buffer in bytes.
Fork(): The fork() system call is used by processes to create copies of themselves. It is one of the methods used
the most frequently in operating systems to create processes. When a parent process creates a child process,
the parent process’s execution is suspended until the child process is finished. The parent process regains control
once the child process has finished running.
Exit(): A system call called exit() is used to terminate a program. In environments with multiple threads, this call
indicates that the thread execution is finished. After using the exit() system function, the operating system
recovers the resources used by the process.
If a system call occur, we have to pass parameter to the Kernal part of the Operating system.
For example look at the given open() system call:
//function call example
#include <fcntl.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
const char* pathname = "example.txt";
int flags = O_RDONLY;
mode_t mode = 0644;
if (fd == -1) {
perror("Error opening file");
return 1;
}
close(fd);
return 0;
}
2. Address of The Block is Passed as Parameters
It can be applied when the number of parameters are greater than the number of registers.
Parameters are stored in blocks or table.
The address of the block is passed to a register as a parameter.
Most commonly used in Linux and Solaris.
Here is the C program code:
//Address of the block is passed as parameters
#include <stdio.h>
#include <fcntl.h>
int main() {
const char *pathname = "example.txt";
int flags = O_RDONLY;
mode_t mode = 0644;
int params[3];
// Block of data(parameters) in array
params[0] = (int)pathname;
params[1] = flags;
params[2] = mode;
if (fd == -1) {
perror("Error opening file");
return 1;
}
close(fd);
return 0;
}
3. Parameters Are Pushed in a Stack
In this method parameters can be pushed in using the program and popped out using the operating
system
So the Kernal can easily access the data by retrieving information from the top of the stack.
Here is the C program code
//parameters are pushed into the stack
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
const char *pathname = "example.txt";
int flags = O_RDONLY;
mode_t mode = 0644;
int fd;
asm volatile(
"mov %1, %%rdi\n"
"mov %2, %%rsi\n"
"mov %3, %%rdx\n"
"mov $2, %%rax\n"
"syscall"
: "=a" (fd)
: "r" (pathname), "r" (flags), "r" (mode)
: "%rdi", "%rsi", "%rdx"
);
if (fd == -1) {
perror("Error opening file");
return 1;
}
close(fd);
return 0;
}
Advantages of System Calls
Access to Hardware Resources: System calls allow programs to access hardware resources such as disk
drives, printers, and network devices.
Memory Management: System calls provide a way for programs to allocate and deallocate memory, as
well as access memory-mapped hardware devices.
Process Management: System calls allow programs to create and terminate processes, as well as manage
inter-process communication.
Security: System calls provide a way for programs to access privileged resources, such as the ability to
modify system settings or perform operations that require administrative permissions.
Standardization: System calls provide a standardized interface for programs to interact with the
operating system, ensuring consistency and compatibility across different hardware platforms and
operating system versions.
Disadvantages of System Call
Performance Overhead: System calls involve switching between user mode and kernel mode, which can
slow down program execution.
Security Risks: Improper use or vulnerabilities in system calls can lead to security breaches or
unauthorized access to system resources.
Error Handling Complexity: Handling errors in system calls, such as resource allocation failures or
timeouts, can be complex and require careful programming.
Compatibility Challenges: System calls may vary between different operating systems, requiring
developers to write code that works across multiple platforms.
Resource Consumption: System calls can consume significant system resources, especially in
environments with many concurrent processes making frequent calls.
Access to
Direct access to system resources Limited access to system resources
Resources
Higher risk of causing system crashes or Less risky in terms of system crashes or
Risks
security vulnerabilities security vulnerabilities
I. UNIX Architecture
What is System Programming?
o The art of writing system software
o System software lives at a low level, interfacing directly with the kernel and core system libraries.
o System software includes your shell and your text editor, your compiler and your debugger, your
core utilities and system daemons.
o These components are entirely system software, based on the kernel and the C library.
o traditional system programming—Apache, bash, cp, Emacs, init, gcc, gdb, glibc, ls, mv, vim, and
X.
o The umbrella of system programming often includes kernel development, or at least device
driver writing
o There are three cornerstones to system programming in Linux: system calls, the C library, and
the C compiler. Each deserves an introduction.
o Programming directly interacting with the operating system kernel.
o Focus on low-level resource management, hardware access, and process control.
o Essential for developing system utilities, device drivers, and embedded systems.
Monolithic Kernel vs. Microkernel:
o Monolithic: All OS services run in kernel space (e.g., Linux).
Advantages: Performance, simplicity.
Disadvantages: Stability, security (one crash can bring down the whole system).
o Microkernel: Minimal kernel functionalities, most services run in user space (e.g., Mach, QNX).
Advantages: Stability, security, modularity.
Disadvantages: Performance overhead due to inter-process communication.
Layered Structure of Unix:
o Hardware: The physical computer system.
o Kernel: The core of the OS, responsible for:
Process management (scheduling, context switching).
Memory management (virtual memory, allocation).
File system management (storage, access control).
Device drivers (hardware interaction).
Inter-process communication (IPC).
o System Calls: The interface between user-space programs and the kernel.
Examples: open(), read(), write(), fork(), exec(), exit().
o Shell: A command-line interpreter that allows users to interact with the OS.
o User Applications: Programs built on top of the OS.
Main Concepts:
o Everything is a file: Treating hardware devices and inter-process communication mechanisms as
files.
o Hierarchical file system: A tree-like structure for organizing files and directories.
o Pipes and Redirection: Connecting processes through pipelines and redirecting input/output.
II. The C Library (libc)
Purpose: A set of pre-written functions that provide common functionalities to C programs.
Standardization: Defined by ANSI/ISO C standards.
Major Functionality:
o Input/Output (I/O): stdio.h (e.g., printf(), scanf(), fopen(), fread(), fwrite()).
o String Manipulation: string.h (e.g., strcpy(), strlen(), strcmp()).
o Memory Management: stdlib.h (e.g., malloc(), calloc(), free()).
o Mathematics: math.h (e.g., sin(), cos(), sqrt()).
o Time and Date: time.h (e.g., time(), localtime()).
o System Calls (Wrappers): The C library often provides wrappers around system calls, making
them easier to use.
Implementation Variations: Different Unix systems have different implementations of libc (e.g., glibc on
Linux, musl on Alpine Linux, bionic on Android). These can have slight behavioral differences.
Static vs. Dynamic Linking:
o Static: The library code is copied into the executable at compile time. Larger executable, but no
external dependencies.
o Dynamic: The library is linked at runtime. Smaller executable, but requires the library to be
present on the system.
III. The C Compiler (gcc/clang)
Purpose: Translates C source code into executable machine code.
Compilation Process:
o Preprocessing: Handles preprocessor directives (e.g., #include, #define).
o Compilation: Translates preprocessed code into assembly code.
o Assembly: Converts assembly code into object code (machine code modules).
o Linking: Combines object code modules and libraries to create the final executable.
Key Compiler Options:
o -c: Compile to object code only (no linking).
o -o <output_file>: Specify the output file name.
o -I <include_path>: Add a directory to the include path.
o -L <library_path>: Add a directory to the library path.
o -l <library_name>: Link with a specific library.
o -Wall: Enable all warnings. Crucial for writing robust code.
o -Werror: Treat warnings as errors.
o -O0, -O1, -O2, -O3: Optimization levels.
o -g: Include debugging information.
Understanding Linking Errors: Common problems and how to resolve them.
Compiler Standards Support: -std=c99, -std=c11, -std=gnu99, etc. Specify which C standard the compiler
should adhere to.
IV. API and ABI
API (Application Programming Interface): The set of functions, procedures, data structures, and
protocols that a software component provides to support requests from other software components. It
is a source-level interface.
ABI (Application Binary Interface): The low-level interface between two binary program modules. It
defines:
o Data types: Sizes, alignment, and representations of data.
o Calling conventions: How arguments are passed to functions, and how return values are
returned.
o System call conventions: How user-space programs make requests to the kernel.
o Object file format: Structure and format of object files and executables.
Importance: ABI compatibility is crucial for ensuring that pre-compiled libraries and executables can run
correctly across different versions of a system or on different systems. An incompatible ABI will result in
crashes or undefined behavior.
Impact of Standards: Standards like POSIX and the Single UNIX Specification aim to standardize both APIs
and ABIs to promote portability.
Example Differences: Word sizes (32-bit vs. 64-bit), endianness (big-endian vs. little-endian), structure
packing.
V. Files and Directories
File System Hierarchy:
o /: Root directory.
o /bin: Essential user command binaries.
o /sbin: Essential system administration binaries.
o /usr: User-related programs and data.
o /etc: System configuration files.
o /home: User home directories.
o /tmp: Temporary files.
o /var: Variable data (logs, databases).
File Attributes:
o Name, size, modification time, permissions (read, write, execute).
o User ID (UID), Group ID (GID).
o File type (regular file, directory, symbolic link, device file, etc.).
System Calls for File Manipulation:
o open(): Open a file for reading, writing, or both.
o close(): Close a file descriptor.
o read(): Read data from a file.
o write(): Write data to a file.
o lseek(): Move the file pointer.
o stat(), fstat(), lstat(): Get file status information.
o unlink(): Delete a file.
o rename(): Rename a file.
o chmod(): Change file permissions.
o chown(): Change file owner and group.
System Calls for Directory Manipulation:
o mkdir(): Create a directory.
o rmdir(): Remove a directory.
o opendir(): Open a directory stream.
o readdir(): Read a directory entry.
o closedir(): Close a directory stream.
o chdir(): Change the current working directory.
o getcwd(): Get the current working directory.
File Permissions and Access Control: Understanding the Unix permission model (user, group, others;
read, write, execute). Using chmod and chown.
Symbolic Links vs. Hard Links: Differences and use cases.
VI. Unix Standardization
Motivation: To ensure portability of applications across different Unix systems.
Key Standards:
o ISO-C (ANSI C): Standardizes the C programming language itself. Ensures that C code written
according to the standard will compile and run correctly on any platform with a conforming C
compiler.
o IEEE POSIX (Portable Operating System Interface): Defines a set of APIs and command-line
interfaces for Unix-like operating systems. Focuses on operating system services, such as file I/O,
process management, and inter-process communication.
o The Single UNIX Specification (SUS): A stricter superset of POSIX. It defines a complete system,
including the C library, system calls, and utilities. A system that conforms to SUS is branded as
"UNIX."
o FIPS (Federal Information Processing Standards): Standards developed by the U.S. National
Institute of Standards and Technology (NIST) for use in U.S. federal government computer
systems. Often references or incorporates other standards (like POSIX).
Relationship between Standards:
o ISO C defines the C programming language.
o POSIX defines a set of operating system interfaces that are typically accessed through the C
programming language (using the C library).
o SUS builds upon POSIX, adding further requirements and specifications for a complete Unix
system.
Impact on System Programming: Standards provide a common baseline for developers, making it easier
to write portable code.
Limitations of Standards: Standards can sometimes lag behind the latest technological developments.
Also, not all Unix systems fully conform to all standards.
VII. Unix System Implementations
BSD (Berkeley Software Distribution):
o Descended from the original Unix developed at Bell Labs.
o Known for its permissive licensing, which has allowed it to be incorporated into many other
systems.
o Examples: FreeBSD, NetBSD, OpenBSD, macOS (Darwin kernel).
Linux:
o An open-source Unix-like operating system kernel.
o Developed by Linus Torvalds.
o Used in a wide range of devices, from embedded systems to servers.
o Often combined with the GNU userland tools (e.g., bash, coreutils, gcc).
macOS (previously OS X):
o Based on the Darwin kernel, which is a hybrid kernel derived from BSD and Mach.
o Provides a user-friendly graphical interface on top of a Unix-like operating system.
Solaris:
o Developed by Sun Microsystems (now Oracle).
o Known for its advanced features, such as ZFS file system and DTrace dynamic tracing.
Comparative Analysis:
o Kernel architecture: Monolithic vs. hybrid vs. microkernel.
o File system: Ext4 (Linux), ZFS (Solaris), APFS (macOS), UFS (BSD).
o Process management: Scheduling algorithms, memory management techniques.
o Security features: Access control mechanisms, security modules.
o Standards compliance: POSIX, SUS, etc.
VIII. Limits, Options, and Primitive System Datatypes
Limits: Maximum values for various system resources (e.g., maximum number of open files, maximum
size of a file).
o Defined in limits.h.
o Accessed using getrlimit() and setrlimit().
o Examples: OPEN_MAX, ARG_MAX, CHILD_MAX.
Options: Features supported by a specific Unix system implementation.
o Determined using sysconf(), pathconf(), and fpathconf().
o Defined in unistd.h.
o Examples: _POSIX_VERSION, _XOPEN_VERSION.
Primitive System Datatypes: Integer and other data types defined by POSIX standards to ensure
portability across different architectures.
o Defined in <sys/types.h> and other system headers.
o Examples: pid_t, uid_t, gid_t, off_t, size_t, ssize_t, time_t.
Importance: Using limits, options, and standard data types ensures that your code is more portable and
robust.
Example Scenario: Determining the maximum length of a file name on a specific file system.
IX. Conflicts Between Standards and Implementations
Version Differences: Older systems may not fully implement newer versions of POSIX or SUS.
Optional Features: POSIX allows some features to be optional. An application relying on an optional
feature may not be portable.
Implementation-Specific Extensions: Unix systems often add their own extensions to the standard APIs.
These extensions can provide additional functionality, but they can also reduce portability.
Conflicting Definitions: Sometimes, different standards (or different versions of the same standard) may
define the same function or constant with conflicting meanings.
Practical Implications: Porting code between different Unix systems can be challenging due to these
conflicts. Careful testing and conditional compilation may be necessary. Use Autoconf/Automake to
automatically configure your build environment.
Chapter-3
Process Management
3.1. Process Introduction
3.2. Process Creation and Deletion
3.3. States of a Process
3.4. Process Implementation (Process Table and Control Block)
3.5. Types of Processes in Process Table
3.6. Inter Process Communication
3.7. Multithreading
3.8. CPU Scheduling
3.9. Deadlock
Text Section: A text or code segment contains executable instructions. It is typically a read only section
Stack: The stack contains temporary data, such as function parameters, returns addresses, and local
variables.
Data Section: Contains the global variable.
Heap Section: Dynamically memory allocated to process during its run time.
Attributes of a Process
A process has several important attributes that help the operating system manage and control it. These
attributes are stored in a structure called the Process Control Block (PCB) (sometimes called a task control block).
The PCB keeps all the key information about the process, including:
1. Process ID (PID): A unique number assigned to each process so the operating system can identify it.
2. Process State: This shows the current status of the process, like whether it is running, waiting, or ready
to execute.
3. Priority and other CPU Scheduling Information: Data that helps the operating system decide which
process should run next, like priority levels and pointers to scheduling queues.
4. I/O Information: Information about input/output devices the process is using.
5. File Descriptors: Information about open files files and network connections.
6. Accounting Information: Tracks how long the process has run, the amount of CPU time used, and other
resource usage data.
7. Memory Management Information: Details about the memory space allocated to the process, including
where it is loaded in memory and the structure of its memory layout (stack, heap, etc.).
These attributes in the PCB help the operating system control, schedule, and manage each process effectively.
States of Process
A process is in one of the following states:
New: Newly Created Process (or) being-created process.
Ready: After the creation process moves to the Ready state, i.e. the process is ready for execution.
Running: Currently running process in CPU (only one process at a time can be under execution in a single
processor).
Wait (or Block): When a process requests I/O access.
Complete (or Terminated): The process completed its execution.
Suspended Ready: When the ready queue becomes full, some processes are moved to a suspended
ready state
Suspended Block: When the waiting queue becomes full.
Process Creation
As discussed above, processes in most of the operating systems (both Windows and Linux) form hierarchy. So a
new process is always created by a parent process. The process that creates the new one is called the parent
process, and the newly created process is called the child process. A process can create multiple new processes
while it’s running by using system calls to create them.
1. When a new process is created, the operating system assigns a unique Process Identifier (PID) to it and
inserts a new entry in the primary process table.
2. Then required memory space for all the elements of the process such as program, data, and stack is allocated
including space for its Process Control Block (PCB).
3. Next, the various values in PCB are initialized such as,
1. The process identification part is filled with PID assigned to it in step (1) and also its parent’s PID.
2. The processor register values are mostly filled with zeroes, except for the stack pointer and program
counter. The stack pointer is filled with the address of the stack-allocated to it in step (2) and the program
counter is filled with the address of its program entry point.
3. The process state information would be set to ‘New’.
4. Priority would be lowest by default, but the user can specify any priority during creation. Then the
operating system will link this process to the scheduling queue and the process state would be changed
from ‘New’ to ‘Ready’. Now the process is competing for the CPU.
5. Additionally, the operating system will create some other data structures such as log files or accounting
files to keep track of process activity.
CPU and I/O Bound Processes: If the process is intensive in terms of CPU operations, then it is called CPU
bound process. Similarly, If the process is intensive in terms of I/O operations then it is called I/O bound
process.
How Does a Process Move From One State to Other State?
A process can move between different states in an operating system based on its execution status and resource
availability. Here are some examples of how a process can move between different states:
New to Ready: When a process is created, it is in a new state. It moves to the ready state when the
operating system has allocated resources to it and it is ready to be executed.
Ready to Running: When the CPU becomes available, the operating system selects a process from the
ready queue depending on various scheduling algorithms and moves it to the running state.
Running to Blocked: When a process needs to wait for an event to occur (I/O operation or system call),
it moves to the blocked state. For example, if a process needs to wait for user input, it moves to the
blocked state until the user provides the input.
Running to Ready: When a running process is preempted by the operating system, it moves to the ready
state. For example, if a higher-priority process becomes ready, the operating system may preempt the
running process and move it to the ready state.
Blocked to Ready: When the event a blocked process was waiting for occurs, the process moves to the
ready state. For example, if a process was waiting for user input and the input is provided, it moves to
the ready state.
Running to Terminated: When a process completes its execution or is terminated by the operating
system, it moves to the terminated state.
While creating a process, the operating system performs several operations. To identify the processes, it assigns
a process identification number (PID) to each process. As the operating system supports multi-programming, it
needs to keep track of all the processes. For this task, the process control block (PCB) is used to track the process’s
execution status. Each block of memory contains information about the process state, program counter, stack
pointer, status of opened files, scheduling algorithms, etc.
All this information is required and must be saved when the process is switched from one state to another. When
the process makes a transition from one state to another, the operating system must update information in the
process’s PCB. A Process Control Block (PCB) contains information about the process, i.e. registers, quantum,
priority, etc. The Process Table is an array of PCBs, which logically contains a PCB for all of the current processes
in the system.
Pointer: It is a stack pointer that is required to be saved when the process is switched from one state to
another to retain the current position of the process.
Process state: It stores the respective state of the process.
Process number: Every process is assigned a unique id known as process ID or PID which stores the
process identifier.
Program counter: Program Counter stores the counter, which contains the address of the next
instruction that is to be executed for the process.
Register: Registers in the PCB, it is a data structure. When a processes is running and it’s time slice
expires, the current value of process specific registers would be stored in the PCB and the process would
be swapped out. When the process is scheduled to be run, the register values is read from the PCB and
written to the CPU registers. This is the main purpose of the registers in the PCB.
Memory limits: This field contains the information about memory management system used by the
operating system. This may include page tables, segment tables, etc.
List of Open files: This information includes the list of files opened for a process.
Types of Process
Let us first talk about types of types of processes.
Independent process: An independent process is not affected by the execution of other processes.
Independent processes are processes that do not share any data or resources with other processes. No
inte-process communication required here.
Co-operating process: Interact with each other and share data or resources. A co-operating process can
be affected by other executing processes. Inter-process communication (IPC) is a mechanism that allows
processes to communicate with each other and synchronize their actions. The communication between
these processes can be seen as a method of cooperation between them.
Shared Memory
IPC through Shared Memory is a method where multiple processes are given access to the same region of
memory. This shared memory allows the processes to communicate with each other by reading and writing data
directly to that memory area.
Shared Memory in IPC can be visualized as Global variables in a program which are shared in the entire program
but shared memory in IPC goes beyond global variables, allowing multiple processes to share data through a
common memory space, whereas global variables are restricted to a single process.
Message Passing
IPC through Message Passing is a method where processes communicate by sending and receiving messages to
exchange data. In this method, one process sends a message, and the other process receives it, allowing them to
share information. Message Passing can be achieved through different methods like Sockets, Message Queues
or Pipes.
Sockets provide an endpoint for communication, allowing processes to send and receive messages over a
network. In this method, one process (the server) opens a socket and listens for incoming connections, while the
other process (the client) connects to the server and sends data. Sockets can use different communication
protocols, such as TCP (Transmission Control Protocol) for reliable, connection-oriented communication
or UDP (User Datagram Protocol) for faster, connectionless communication.
Different methods of Inter process Communication (IPC) are as follows:
1. Pipes – A pipe is a unidirectional communication channel used for IPC between two related processes.
One process writes to the pipe, and the other process reads from it.
Types of Pipes are Anonymous Pipes and Named Pipes (FIFOs)
2. Sockets – Sockets are used for network communication between processes running on different hosts.
They provide a standard interface for communication, which can be used across different platforms and
programming languages.
3. Shared memory – In shared memory IPC, multiple processes are given access to a common memory
space. Processes can read and write data to this memory, enabling fast communication between them.
4. Semaphores – Semaphores are used for controlling access to shared resources. They are used to prevent
multiple processes from accessing the same resource simultaneously, which can lead to data corruption.
5. Message Queuing – This allows messages to be passed between processes using either a single queue
or several message queue. This is managed by system kernel these messages are coordinated using an
API.
Process Synchronization
Process Synchronization is the coordination of execution of multiple processes in a multi-process system to
ensure that they access shared resources in a controlled and predictable manner. It aims to resolve the problem
of race conditions and other synchronization issues in a concurrent system.
Lack of Synchronization in Inter Process Communication Environment leads to following problems:
1. Inconsistency: When two or more processes access shared data at the same time without proper
synchronization. This can lead to conflicting changes, where one process’s update is overwritten by
another, causing the data to become unreliable and incorrect.
2. Loss of Data: Loss of data occurs when multiple processes try to write or modify the same shared
resource without coordination. If one process overwrites the data before another process finishes,
important information can be lost, leading to incomplete or corrupted data.
3. Deadlock: Lack of Synchronization leads to Deadlock which means that two or more processes get stuck,
each waiting for the other to release a resource. Because none of the processes can continue, the system
becomes unresponsive and none of the processes can complete their tasks.
Example:
Let consider a Linux code:
>>ps/grep "chrome"/wc
ps command produces list of processes running in linux.
grep command find/count the lines form the output of the ps command.
wc command counts how many words are in the output.
Therefore, three processes are created which are ps, grep and wc. grep takes input from ps and wc takes input
from grep.
From this example, we can understand the concept of cooperative processes, where some processes produce
and others consume, and thus work together. This type of problem must be handled by the operating system, as
it is the manager.
Conditions That Require Process Synchronization
1. Critical Section: It is that part of the program where shared resources are accessed. Only one process
can execute the critical section at a given point of time. If there are no shared resources, then no need
of synchronization mechanisms.
2. Race Condition: It is a situation wherein processes are trying to access the critical section and the final
result depends on the order in which they finish their update. Process Synchronization mechanism need
to ensure that instructions are being executed in a required order only.
3. Pre Emption: Preemption is when the operating system stops a running process to give the CPU to
another process. This allows the system to make sure that important tasks get enough CPU time. This is
important as mainly issues arise when a process has not finished its job on shared resource and got
preempted. The other process might end up reading an inconsistent value if process synchronization is
not done.
Readers-Writers Problem
The Readers-Writers Problem is a classic synchronization problem where multiple processes are involved in
reading and writing data from a shared resource. This problem typically involves two types of processes:
Readers: These processes only read data from the shared resource and do not modify it.
Writers: These processes modify or write data to the shared resource.
The challenge in the Reader-Writer problem is to allow multiple readers to access the shared data simultaneously
without causing issues. However, only one writer should be allowed to write at a time, and no reader should be
allowed to read while a writer is writing. This ensures the integrity and consistency of the data.
Readers-Writers Problem – Solution (Readers Preference Solution)
Readers-Writers Problem – Solution (Writers Preference Solution)
Critical section
It could be visualized using the pseudo-code below –
do{
flag=1;
while(flag); // (entry section)
// critical section
if (!flag)
// remainder section
} while(true);
Strategies for avoiding problems: While deadlocks, starvation, and overhead are mentioned as potential issues,
there are more specific strategies for avoiding or mitigating these problems. For example, using timeouts to
prevent deadlocks, implementing priority inheritance to prevent priority inversion and starvation, or optimizing
lock implementation to reduce overhead.
Examples of critical sections in real-world applications: While the article describes critical sections in a general
sense, it could be useful to provide examples of how critical sections are used in specific real-world applications,
such as database management systems or web servers.
Impact on scalability: The use of critical sections can impact the scalability of a program, particularly in
distributed systems where multiple nodes are accessing shared resources.
In process synchronization, a critical section is a section of code that accesses shared resources such as variables
or data structures, and which must be executed by only one process at a time to avoid race conditions and other
synchronization-related issues.
A critical section can be any section of code where shared resources are accessed, and it typically consists of two
parts: the entry section and the exit section. The entry section is where a process requests access to the critical
section, and the exit section is where it releases the resources and exits the critical section.
To ensure that only one process can execute the critical section at a time, process synchronization mechanisms
such as semaphores and mutexes are used. A semaphore is a variable that is used to indicate whether a resource
is available or not, while a mutex is a semaphore that provides mutual exclusion to shared resources.
When a process enters a critical section, it must first request access to the semaphore or mutex associated with
the critical section. If the resource is available, the process can proceed to execute the critical section. If the
resource is not available, the process must wait until it is released by the process currently executing the critical
section.
Once the process has finished executing the critical section, it releases the semaphore or mutex, allowing another
process to enter the critical section if necessary.
Proper use of critical sections and process synchronization mechanisms is essential in concurrent programming
to ensure proper synchronization of shared resources and avoid race conditions, deadlocks, and other
synchronization-related issues.
Advantages of Critical Section in Process Synchronization
1. Prevents race conditions: By ensuring that only one process can execute the critical section at a time,
race conditions are prevented, ensuring consistency of shared data.
2. Provides mutual exclusion: Critical sections provide mutual exclusion to shared resources, preventing
multiple processes from accessing the same resource simultaneously and causing synchronization-
related issues.
3. Reduces CPU utilization: By allowing processes to wait without wasting CPU cycles, critical sections can
reduce CPU utilization, improving overall system efficiency.
4. Simplifies synchronization: Critical sections simplify the synchronization of shared resources, as only one
process can access the resource at a time, eliminating the need for more complex synchronization
mechanisms.
Disadvantages of Critical Section in Process Synchronization
1. Overhead: Implementing critical sections using synchronization mechanisms like semaphores and
mutexes can introduce additional overhead, slowing down program execution.
2. Deadlocks: Poorly implemented critical sections can lead to deadlocks, where multiple processes are
waiting indefinitely for each other to release resources.
3. Can limit parallelism: If critical sections are too large or are executed frequently, they can limit the
degree of parallelism in a program, reducing its overall performance.
4. Can cause contention: If multiple processes frequently access the same critical section, contention for
the critical section can occur, reducing performance.
Important Points Related to Critical Section in Process Synchronization
1. Understanding the concept of critical section and why it’s important for synchronization.
2. Familiarity with the different synchronization mechanisms used to implement critical sections, such as
semaphores, mutexes, and monitors.
3. Knowledge of common synchronization problems that can arise in critical sections, such as race
conditions, deadlocks, and live locks.
4. Understanding how to design and implement critical sections to ensure proper synchronization of shared
resources and prevent synchronization-related issues.
5. Familiarity with best practices for using critical sections in concurrent programming.
do{ do{
flag[i] = true; flag[j] = true;
turn = j; turn = i;
while (flag[j] && turn == j); while (flag[i] && turn == i);
//critical section //critical section
# Critical Section: Producer produces an item and puts it into the buffer
// Exit section
Lock = 0;
A more formal approach to the Lock Variable method for process synchronization can be seen in the following
code snippet :
C++C
#include <mutex>
#include <condition_variable>
char buffer[SIZE];
int count = 0,
start = 0,
end = 0;
std::mutex mtx;
std::condition_variable cv;
void put(char c)
{
std::unique_lock<std::mutex> lock(mtx);
count++;
buffer[start] = c;
start++;
if (start == SIZE) {
start = 0;
}
cv.notify_all();
}
char get()
{
std::unique_lock<std::mutex> lock(mtx);
while (count == 0) {
cv.wait(lock);
}
count--;
char c = buffer[end];
end++;
if (end == SIZE) {
end = 0;
}
cv.notify_all();
return c;
}
Here we can see a classic implementation of the reader-writer’s problem. The buffer here is the shared memory
and many processes are either trying to read or write a character to it. To prevent any ambiguity of data we
restrict concurrent access by using a lock variable. We have also applied a constraint on the number of
readers/writers that can have access.
Now every Synchronization mechanism is judged on the basis of three primary parameters :
1. Mutual Exclusion.
2. Progress.
3. Bounded Waiting.
Of which mutual exclusion is the most important of all parameters. The Lock Variable doesn’t provide mutual
exclusion in some cases. This fact can be best verified by writing its pseudo-code in the form of an assembly
language code as given below.
1. Load Lock, R0 ; (Store the value of Lock in Register R0.)
2. CMP R0, #0 ; (Compare the value of register R0 with 0.)
3. JNZ Step 1 ; (Jump to step 1 if value of R0 is not 0.)
4. Store #1, Lock ; (Set new value of Lock as 1.)
Enter critical section
5. Store #0, Lock ; (Set the value of lock as 0 again.)
Now let’s suppose that processes P1 and P2 are competing for Critical Section and their sequence of execution
be as follows (initial value of Lock = 0) –
1. P1 executes statement 1 and gets pre-empted.
2. P2 executes statement 1, 2, 3, 4 and enters Critical Section and gets pre-empted.
3. P1 executes statement 2, 3, 4 and also enters Critical Section.
Here initially the R0 of process P1 stores lock value as 0 but fails to update the lock value as 1. So when P2
executes it also finds the LOCK value as 0 and enters Critical Section by setting LOCK value as 1. But the real
problem arises when P1 executes again it doesn’t check the updated value of Lock. It only checks the previous
value stored in R0 which was 0 and it enters critical section.
This is only one possible sequence of execution among many others. Some may even provide mutual exclusion
but we cannot dwell on that. According to murphy’s law “Anything that can go wrong will go wrong“. So like all
easy things the Lock Variable Synchronization method comes with its fair share of Demerits but its a good starting
point for us to develop better Synchronization Algorithms to take care of the problems that we face here.
3.6.6. Semaphores in Process Synchronization
Semaphores are a tool used in operating systems to help manage how different processes (or programs) share
resources, like memory or data, without causing conflicts. A semaphore is a special kind of synchronization data
that can be used only through specific synchronization primitives. Semaphores are used to implement critical
sections, which are regions of code that must be executed by only one process at a time. By using semaphores,
processes can coordinate access to shared resources, such as shared memory or I/O devices.
What is Semaphores?
A semaphore is a synchronization tool used in concurrent programming to manage access to shared resources.
It is a lock-based mechanism designed to achieve process synchronization, built on top of basic locking
techniques.
Semaphores use a counter to control access, allowing synchronization for multiple instances of a resource.
Processes can attempt to access one instance, and if it is not available, they can try other instances. Unlike basic
locks, which allow only one process to access one instance of a resource. Semaphores can handle more complex
synchronization scenarios, involving multiple processes or threads. It help prevent problems like race
conditions by controlling when and how processes access shared data.
The process of using Semaphores provides two operations:
wait (P): The wait operation decrements the value of the semaphore
signal (V): The signal operation increments the value of the semaphore.
When the value of the semaphore is zero, any process that performs a wait operation will be blocked until
another process performs a signal operation.
When a process performs a wait operation on a semaphore, the operation checks whether the value of the
semaphore is >0. If so, it decrements the value of the semaphore and lets the process continue its execution;
otherwise, it blocks the process on the semaphore. A signal operation on a semaphore activates a process
blocked on the semaphore if any, or increments the value of the semaphore by 1. Due to these semantics,
semaphores are also called counting semaphores. The initial value of a semaphore determines how many
processes can get past the wait operation.
Semaphores are required for process synchronization to make sure that multiple processes can safely share
resources without interfering with each other. They help control when a process can access a shared resource,
preventing issues like race conditions.
Types of Semaphores
Semaphores are of two Types:
Binary Semaphore: This is also known as a mutex lock, as they are locks that provide mutual exclusion.
It can have only two values – 0 and 1. Its value is initialized to 1. It is used to implement the solution of
critical section problems with multiple processes and a single resource.
Counting Semaphore: Counting semaphores can be used to control access to a given resource consisting
of a finite number of instances. The semaphore is initialized to the number of resources available. Its
value can range over an unrestricted domain.
Working of Semaphore
A semaphore is a simple yet powerful synchronization tool used to manage access to shared resources in a system
with multiple processes. It works by maintaining a counter that controls access to a specific resource, ensuring
that no more than the allowed number of processes access the resource at the same time.
There are two primary operations that a semaphore can perform:
1. Wait (P operation): This operation checks the semaphore’s value. If the value is greater than 0, the
process is allowed to continue, and the semaphore’s value is decremented by 1. If the value is 0, the
process is blocked (waits) until the semaphore value becomes greater than 0.
2. Signal (V operation): After a process is done using the shared resource, it performs the signal operation.
This increments the semaphore’s value by 1, potentially unblocking other waiting processes and allowing
them to access the resource.
Now let us see how it does so. First, look at two operations that can be used to access and change the value of
the semaphore variable.
A critical section is surrounded by both operations to implement process synchronization. The below image
demonstrates the basic mechanism of how semaphores are used to control access to a critical section in a multi-
process environment, ensuring that only one process can access the shared resource at a time
Now, let us see how it implements mutual exclusion. Let there be two processes P1 and P2 and a semaphore s is
initialized as 1. Now if suppose P1 enters in its critical section then the value of semaphore s becomes 0. Now if
P2 wants to enter its critical section then it will wait until s > 0, this can only happen when P1 finishes its critical
section and calls V operation on semaphore s.
This way mutual exclusion is achieved. Look at the below image for details which is a Binary semaphore.
Implementation – Binary Semaphores
C++
struct semaphore {
};
P(semaphore s)
{
if (s.value == 1) {
s.value = 0;
}
else {
// add the process to the waiting queue
q.push(P) sleep();
}
}
V(semaphore s)
{
if (s.q is empty) {
s.value = 1;
}
else {
int value;
};
P(Semaphore s)
{
s.value = s.value - 1;
if (s.value < 0) {
V(Semaphore s)
{
s.value = s.value + 1;
if (s.value <= 0) {
Advantages of Semaphores
Semaphore is a simple and effective mechanism for process synchronization
Supports coordination between multiple processes. By controlling the access to critical sections,
semaphores help in managing multiple processes without them interfering with each other.
When used correctly, semaphores can help avoid deadlocks by managing access to resources efficiently
and ensuring that no process is indefinitely blocked from accessing necessary resources.
Semaphores help prevent race conditions by ensuring that only one process can access a shared resource
at a time.
Provides a flexible and robust way to manage shared resources.
Disadvantages of Semaphores
It Can lead to performance degradation due to overhead associated with wait and signal operations.
If semaphores are not managed carefully, they can lead to deadlock. This often occurs when semaphores
are not released properly or when processes acquire semaphores in an inconsistent order.
It can cause performance issues in a program if not used properly.
It can be difficult to debug and maintain. Debugging systems that rely heavily on semaphores can be
challenging, as it is hard to track the state of each semaphore and ensure that all processes are correctly
synchronized
It can be prone to race conditions and other synchronization problems if not used correctly.
It can be vulnerable to certain types of attacks, such as denial of service attacks.
7. Reader-Writer Problem
In Reader-Writer problem Synchronizing access to shared data where multiple readers can read the data
simultaneously, but writers need exclusive access to modify it. In simple terms imagine a library where multiple
readers and writers come and all readers want to read a book, and some people(writers) want to update or edit
the book. That’s why we need a system to ensure that these actions are done smoothly without errors or
conflicts.
Multiple Readers and Writers: Processes that need to access a shared resource(data).
Data: Shared resources represented by a Semaphore.
Semaphore Value for Reader: Process that reads shared data, Can access simultaneously(value>1, more
than one reader can access at the same time)
Semaphore Value for Writers: Processes that modify shared data need exclusive access(value =1, one at
a time)
Solution –
Readers Preference Solution
Writers Preference Solution
Inter-Process Communication (IPC) is necessary for processes to communicate and share data. While basic
communication between processes may sound simple, certain situations can cause issues that need specific
solutions. These situations are known as Classical IPC Problems, which involve managing synchronization,
avoiding deadlock, and ensuring that resources are accessed in a controlled manner.
Some of the well-known Inter Process Communication problems are:
1. Producer Consumer Problem
2. Readers-Writers Problem
3. Dining Philosophers Problem
Producer Consumer Problem
The Producer-Consumer Problem involves two types of processes: the Producer, which creates data, and the
Consumer, which processes that data. The challenge is ensuring that the Producer doesn't overfill the buffer, and
the Consumer doesn't try to consume data from an empty buffer.
Key Problems in the Producer-Consumer Problem:
1. Buffer Overflow: If the producer tries to add data when the buffer is full, there will be no space for new
data, causing the producer to be blocked.
2. Buffer Underflow: If the consumer tries to consume data when the buffer is empty, it has nothing to
consume, causing the consumer to be blocked.
Solution to Producer Consumer Problem
This problem can be solved using synchronization techniques such as semaphores or mutexes to control access
to the shared buffer and ensure proper synchronization between the Producer and Consumer.
Producer-Consumer Problem - Solution (using Semaphores)
Reader-Writer Problem
The Reader-Writer Problem involves multiple processes that need to read from and write to shared data. Here,
we have two types of processes: Readers, which only read the data, and Writers, which can modify the data.
Readers: These processes only read data from the shared resource and do not modify it.
Writers: These processes modify or write data to the shared resource.
The challenge in the Reader-Writer problem is to allow multiple readers to access the shared data simultaneously
without causing issues. However, only one writer should be allowed to write at a time, and no reader should be
allowed to read while a writer is writing. This ensures the integrity and consistency of the data.
Solution to Reader-Writer Problem
There are two fundamental solutions to the Readers-Writers problem:
Readers Preference: In this solution, readers are given preference over writers. That means that till
readers are reading, writers will have to wait. The Writers can access the resource only when no reader
is accessing it.
Writer’s Preference: Preference is given to the writers. It simply means that, after arrival, the writers can
go ahead with their operations, though perhaps there are readers currently accessing the resource.
Readers-Writers Problem - Solution (Readers Preference Solution)
Readers-Writers Problem - Solution (Writers Preference Solution)
Dining Philosophers Problem
The Dining Philosopher Problem is a classic synchronization and concurrency problem that deals with resource
sharing, deadlock, and starvation in systems where multiple processes require limited resources. In this article,
we will discuss the Dining Philosopher Problem in detail along with proper implementation.
The Dining Philosopher Problem involves ‘n’ philosophers sitting around a circular table. Each philosopher
alternates between two states: thinking and eating. To eat, a philosopher needs two chopsticks, one on their left
and one on their right. However, the number of chopsticks is equal to the number of philosophers, and each
chopstick is shared between two neighboring philosophers.
The standard problem considers the value of ‘n’ as 5 i.e. we deal with 5 Philosophers sitting around a circular
table.
Solution to Dining Philosophers Problem
Solutions to this problem typically involve using synchronization techniques like semaphores or mutexes to
ensure that the philosophers don’t deadlock. One common approach is to use a monitor to coordinate access to
the forks, allowing each philosopher to pick up and put down forks in a way that prevents deadlock.
Dining Philosophers Problem - Solution (using Semaphores)
Dining-Philosophers Problem - Solution (Using Monitors)
// function declaration
void sighup();
void sigint();
void sigquit();
void main()
{
int pid;
/* child */
if (pid == 0) {
signal(SIGHUP, sighup);
signal(SIGINT, sigint);
signal(SIGQUIT, sigquit);
for (;;)
/* loop forever */
;
}
/* parent */
else
/* reset signal */
signal(SIGHUP, sighup);
write(STDOUT_FILENO, "CHILD: I have received a SIGHUP\n", 31);
}
/* reset signal */
signal(SIGINT, sigint);
write(STDOUT_FILENO, "CHILD: I have received a SIGINT\n", 32);
}
In the Operating System, Mutex and Semaphores are kernel resources that provide synchronization services
(also known as synchronization primitives). Synchronization is required when multiple processes are executing
concurrently, to avoid conflicts between processes using shared resources. In this article we will see differences
between Mutex and Semaphore, their advantages and disadvantages.
What is Mutex?
A mutex is different from a binary semaphore, which provides a locking mechanism. It stands for Mutual
Exclusion Object. Mutex is mainly used to provide mutual exclusion to a specific portion of the code so that the
process can execute and work with a particular section of the code at a particular time. A mutex enforces strict
ownership. Only the thread that locks the mutex can unlock it. It is specifically used for locking a resource to
ensure that only one thread accesses it at a time. Due to this strict ownership, a mutex is not only typically used
for signaling between threads, but it is used for mutual exclusion also to ensuring that a resource is accessed by
only one thread at a time.
Mutex uses a priority inheritance mechanism to avoid priority inversion issues. The priority inheritance
mechanism keeps higher-priority processes in the blocked state for the minimum possible time. However, this
cannot avoid the priority inversion problem, but it can reduce its effect up to an extent.
Advantages of Mutex
No race condition arises, as only one process is in the critical section at a time.
Data remains consistent and it helps in maintaining integrity.
It is a simple locking mechanism that into a critical section and is released while leaving the critical
section.
Disadvantages of Mutex
If after entering into the critical section, the thread sleeps or gets preempted by a high-priority process,
no other thread can enter into the critical section. This can lead to starvation.
When the previous thread leaves the critical section, then only other processes can enter into it, there is
no other mechanism to lock or unlock the critical section.
Implementation of mutex can lead to busy waiting, which leads to the wastage of the CPU cycle.
Using Mutex
The producer-consumer problem: Consider the standard producer-consumer problem. Assume, we have a
buffer of 4096-byte length. A producer thread collects the data and writes it to the buffer. A consumer thread
processes the collected data from the buffer. The objective is, that both the threads should not run at the same
time.
Solution: A mutex provides mutual exclusion, either producer or consumer can have the key (mutex) and proceed
with their work. As long as the buffer is filled by the producer, the consumer needs to wait, and vice versa. At
any point in time, only one thread can work with the entire buffer. The concept can be generalized using
semaphore.
Mutex
What is Semaphore?
A semaphore is a non-negative integer variable that is shared between various threads. Semaphore works upon
signaling mechanism, in this a thread can be signaled by another thread. It provides a less restrictive control
mechanism. Any thread can invoke signal() (also known as release() or up()), and any other thread can
invoke wait() (also known as acquire() or down()). There is no strict ownership in semaphores, meaning the
thread that signals doesn’t necessarily have to be the same one that waited. Semaphores are often used for
coordinating signaling between threads. Semaphore uses two atomic operations for process synchronisation:
Wait (P)
Signal (V)
Advantages of Semaphore
Multiple threads can access the critical section at the same time.
Semaphores are machine-independent.
Only one process will access the critical section at a time, however, multiple threads are allowed.
Semaphores are machine-independent, so they should be run over microkernel.
Flexible resource management.
Disadvantages of Semaphore
It has priority inversion.
Semaphore operations (Wait, Signal) must be implemented in the correct manner to avoid deadlock.
It leads to a loss of modularity, so semaphores can’t be used for large-scale systems.
Semaphore is prone to programming error and this can lead to deadlock or violation of mutual exclusion
property.
Operating System has to track all the calls to wait and signal operations.
Using Semaphore
The producer-consumer problem: Consider the standard producer-consumer problem. Assume, we have a
buffer of 4096-byte length. A producer thread collects the data and writes it to the buffer. A consumer thread
processes the collected data from the buffer. The objective is, both the threads should not run at the same time.
Solution: A semaphore is a generalized mutex. instead a single buffer, we can split the 4 KB buffer into four 1 KB
buffers (identical resources). A semaphore can be associated with these four buffers. The consumer and producer
can work on different buffers at the same time.
Semaphore
Difference Between Mutex and Semaphore
Mutex Semaphore
Mutex works upon the locking mechanism. Semaphore uses signaling mechanism.
A mutex can only be modified by the process Semaphore work with two atomic operations (Wait,
that is requesting or releasing a resource. signal) which can modify it.
If the mutex is locked then the process needs to If the process needs a resource, and no resource is free.
wait in the process queue, and mutex can only So, the process needs to perform a wait operation until
be accessed once the lock is released. the semaphore value is greater than zero.
Monitors are a higher-level synchronization construct that simplifies process synchronization by providing a high-
level abstraction for data access and synchronization. Monitors are implemented as programming language
constructs, typically in object-oriented languages, and provide mutual exclusion, condition variables, and data
encapsulation in a single construct.
1. A monitor is essentially a module that encapsulates a shared resource and provides access to that
resource through a set of procedures. The procedures provided by a monitor ensure that only one
process can access the shared resource at any given time, and that processes waiting for the resource
are suspended until it becomes available.
2. Monitors are used to simplify the implementation of concurrent programs by providing a higher-level
abstraction that hides the details of synchronization. Monitors provide a structured way of sharing data
and synchronization information, and eliminate the need for complex synchronization primitives such as
semaphores and locks.
3. The key advantage of using monitors for process synchronization is that they provide a simple, high-level
abstraction that can be used to implement complex concurrent systems. Monitors also ensure that
synchronization is encapsulated within the module, making it easier to reason about the correctness of
the system.
However, monitors have some limitations. For example, they can be less efficient than lower-level
synchronization primitives such as semaphores and locks, as they may involve additional overhead due to their
higher-level abstraction. Additionally, monitors may not be suitable for all types of synchronization problems,
and in some cases, lower-level primitives may be required for optimal performance.
The monitor is one of the ways to achieve Process synchronization. The monitor is supported by programming
languages to achieve mutual exclusion between processes. For example Java Synchronized methods. Java
provides wait() and notify() constructs.
1. It is the collection of condition variables and procedures combined together in a special kind of module
or a package.
2. The processes running outside the monitor can’t access the internal variable of the monitor but can call
procedures of the monitor.
3. Only one process at a time can execute code inside monitors.
Syntax:
Condition Variables: Two different operations are performed on the condition variables of the monitor.
Wait.
signal.
let say we have 2 condition variables condition x, y; // Declaring variable Wait operation x.wait() : Process
performing wait operation on any condition variable are suspended. The suspended processes are placed in block
queue of that condition variable. Note: Each condition variable has its unique block queue. Signal
operation x.signal(): When a process performs signal operation on condition variable, one of the blocked
processes is given chance.
If (x block queue empty)
// Ignore signal
else
// Resume a process from block queue.
Advantages of Monitor: Monitors have the advantage of making parallel programming easier and less error
prone than using techniques such as semaphore. Disadvantages of Monitor: Monitors have to be implemented
as part of the programming language . The compiler must generate code for them. This gives the compiler the
additional burden of having to know what operating system facilities are available to control access to critical
sections in concurrent processes. Some languages that do support monitors are Java,C#,Visual Basic,Ada and
concurrent Euclid.
Reading Assignment
3.7. Multithreading
3.7.1. Thread
3.7.2. Threads and its types
3.7.3. Operating System | User Level thread Vs Kernel Level thread
3.7.4. Process-based and Thread-based Multitasking
3.7.5. Multi-threading models
3.6.6. Benefits of Multithreading
3.6.7. Operating System | Remote Procedure call (RPC)
3.7.1. Thread
A thread is a single sequence stream within a process. Threads are also called lightweight processes as they
possess some of the properties of processes. Each thread belongs to exactly one process.
In an operating system that supports multithreading, the process can consist of many threads. But
threads can be effective only if the CPU is more than 1 otherwise two threads have to context switch for
that single CPU.
All threads belonging to the same process share – code section, data section, and OS resources (e.g. open
files and signals)
But each thread has its own (thread control block) – thread ID, program counter, register set, and a stack
Any operating system process can execute a thread. we can say that single process can have multiple
threads.
Why Do We Need Thread?
Threads run in concurrent manner that improves the application performance. Each such thread has its
own CPU state and stack, but they share the address space of the process and the environment. For
example, when we work on Microsoft Word or Google Docs, we notice that while we are typing, multiple
things happen together (formatting is applied, page is changed and auto save happens).
Threads can share common data so they do not need to use inter-process communication. Like the
processes, threads also have states like ready, executing, blocked, etc.
Priority can be assigned to the threads just like the process, and the highest priority thread is scheduled
first.
Each thread has its own Thread Control Block (TCB). Like the process, a context switch occurs for the
thread, and register contents are saved in (TCB). As threads share the same address space and resources,
synchronization is also required for the various activities of the thread.
Components of Threads
These are the basic components of the Operating System.
Stack Space: Stores local variables, function calls, and return addresses specific to the thread.
Register Set: Hold temporary data and intermediate results for the thread’s execution.
Program Counter: Tracks the current instruction being executed by the thread.
Types of Thread in Operating System
Threads are of two types. These are described below.
User Level Thread
Kernel Level Thread
Threads
1. User Level Thread
User Level Thread is a type of thread that is not created using system calls. The kernel has no work in the
management of user-level threads. User-level threads can be easily implemented by the user. In case when user-
level threads are single-handed processes, kernel-level thread manages them. Let’s look at the advantages and
disadvantages of User-Level Thread.
Advantages of User-Level Threads
Implementation of the User-Level Thread is easier than Kernel Level Thread.
Context Switch Time is less in User Level Thread.
User-Level Thread is more efficient than Kernel-Level Thread.
Because of the presence of only Program Counter, Register Set, and Stack Space, it has a simple
representation.
Disadvantages of User-Level Threads
The operating system is unaware of user-level threads, so kernel-level optimizations, like load balancing
across CPUs, are not utilized.
If a user-level thread makes a blocking system call, the entire process (and all its threads) is blocked,
reducing efficiency.
User-level thread scheduling is managed by the application, which can become complex and may not be
as optimized as kernel-level scheduling.
2. Kernel Level Threads
A kernel Level Thread is a type of thread that can recognize the Operating system easily. Kernel Level Threads
has its own thread table where it keeps track of the system. The operating System Kernel helps in managing
threads. Kernel Threads have somehow longer context switching time. Kernel helps in the management of
threads.
Advantages of Kernel-Level Threads
Kernel-level threads can run on multiple processors or cores simultaneously, enabling better utilization
of multicore systems.
The kernel is aware of all threads, allowing it to manage and schedule them effectively across available
resources.
Applications that block frequency are to be handled by the Kernel-Level Threads.
The kernel can distribute threads across CPUs, ensuring optimal load balancing and system performance.
Disadvantages of Kernel-Level threads
Context switching between kernel-level threads is slower compared to user-level threads because it
requires mode switching between user and kernel space.
Managing kernel-level threads involves frequent system calls and kernel interactions, leading to
increased CPU overhead.
A large number of threads may overload the kernel scheduler, leading to potential performance
degradation in systems with many threads.
Implementation of this type of thread is a little more complex than a user-level thread.
What is Multi-Threading?
A thread is also known as a lightweight process. The idea is to achieve parallelism by dividing a process into
multiple threads. For example, in a browser, multiple tabs can be different threads. MS Word uses multiple
threads: one thread to format the text, another thread to process inputs, etc. More advantages of multithreading
are discussed below.
Multithreading is a technique used in operating systems to improve the performance and responsiveness of
computer systems. Multithreading allows multiple threads (i.e., lightweight processes) to share the same
resources of a single process, such as the CPU, memory, and I/O devices.
Single Threaded vs Multi-threaded Process
Multithreading can be done without OS support, as seen in Java’s multithreading model. In Java, threads are
implemented using the Java Virtual Machine (JVM), which provides its own thread management. These threads,
also called user-level threads, are managed independently of the underlying operating system.
Application itself manages the creation, scheduling, and execution of threads without relying on the operating
system’s kernel. The application contains a threading library that handles thread creation, scheduling, and
context switching. The operating system is unaware of User-Level threads and treats the entire process as a
single-threaded entity.
Benefits of Thread in Operating System
Responsiveness: If the process is divided into multiple threads, if one thread completes its execution,
then its output can be immediately returned.
Faster context switch: Context switch time between threads is lower compared to the process context
switch. Process context switching requires more overhead from the CPU.
Effective utilization of multiprocessor system: If we have multiple threads in a single process, then we
can schedule multiple threads on multiple processors. This will make process execution faster.
Resource sharing: Resources like code, data, and files can be shared among all threads within a process.
Note: Stacks and registers can’t be shared among the threads. Each thread has its own stack and
registers.
Communication: Communication between multiple threads is easier, as the threads share a common
address space. while in the process we have to follow some specific communication techniques for
communication between the two processes.
Enhanced throughput of the system: If a process is divided into multiple threads, and each thread
function is considered as one job, then the number of jobs completed per unit of time is increased, thus
increasing the throughput of the system.
Types of Threads
There are two main types of threads User Level Thread and Kernal Level Thread let’s discuss each one by one in
detail:
User Level Thread (ULT)
User Level Thread is implemented in the user level library, they are not created using the system calls. Thread
switching does not need to call OS and to cause interrupt to Kernel. Kernel doesn’t know about the user level
thread and manages them as if they were single-threaded processes.
Advantages of ULT
Can be implemented on an OS that doesn’t supportmultithreading .
Simple representation since thread has onlyprogram counter , register set, stack space.
Simple to create since no intervention of kernel.
Thread switching is fast since no OS calls need to be made.
Disadvantages of ULT
No or less co-ordination among the threads and Kernel.
If one thread causes a page fault, the entire process blocks.
Kernel Level Thread (KLT)
Kernel knows and manages the threads. Instead of thread table in each process, the kernel itself has thread table
(a master one) that keeps track of all the threads in the system. In addition kernel also maintains the traditional
process table to keep track of the processes. OS kernel provides system call to create and manage threads.
Advantages of KLT
Since kernel has full knowledge about the threads in the system, scheduler may decide to give more time
to processes having large number of threads.
Good for applications that frequently block.
Disadvantages of KLT
Slow and inefficient.
It requires thread control block so it is an overhead.
Threading Issues
The fork() and exec() System Calls : The semantics of the fork() and exec() system calls change in a
multithreaded program. If one thread in a program calls fork(), does the new process duplicate all
threads, or is the new process single-threaded? Some UNIX systems have chosen to have two versions
of fork(), one that duplicates all threads and another that duplicates only the thread that invoked the
fork() system call. The exec() system , That is, if a thread invokes the exec() system call , the program
specified in the parameter to exec() will replace the entire process—including all threads.
Signal Handling : A signal is used in UNIX systems to notify a process that a particular event has occurred.
A signal may be received either synchronously or asynchronously depending on the source of and the
reason for the event being signaled. All signals, whether synchronous or asynchronous, follow the same
pattern:1. A signal is generated by the occurrence of a particular event.2. The signal is delivered to a
process.3. Once delivered, the signal must be handled. A signal may be handled by one of two possible
handlers: 1. A default signal handler .2. A user-defined signal handler. Every signal has a default signal
handler that the kernel runs when handling that signal. This default action can be overridden by a user-
defined signal handler that is called to handle the signal.
Thread Cancellation : Thread cancellation involves terminating a thread before it has completed. For
example, if multiple threads are concurrently searching through a database and one thread returns the
result, the remaining threads might be canceled. Another situation might occur when a user presses a
button on a web browser that stops a web page from loading any further. Often, a web page loads using
several threads—each image is loaded in a separate thread. When a user presses the stop button on the
browser, all threads loading the page are canceled. A thread that is to be canceled is often referred to as
the target thread. Cancellation of a target thread may occur in two different scenarios:1. Asynchronous
cancellation. One thread immediately terminates the target thread.2. Deferred cancellation. The target
thread periodically checks whether it should terminate, allowing it an opportunity to terminate itself in
an orderly fashion.
Thread-Local Storage : Threads belonging to a process share the data of the process. Indeed, this data
sharing provides one of the benefits of multithreaded programming. However, in some circumstances,
each thread might need its own copy of certain data. We will call such data thread-local storage (or TLS.)
For example, in a transaction-processing system, we might service each transaction in a separate thread.
Furthermore, each transaction might be assigned a unique identifier. To associate each thread with its
unique identifier, we could use thread-local storage.
Scheduler Activations : One scheme for communication between the user-thread library and the kernel
is known as scheduler activation. It works as follows: The kernel provides an application with a set of
virtual processors (LWPs), and the application can schedule user threads onto an available virtual
processor.
Advantages of Threading
Responsiveness: A multithreaded application increases responsiveness to the user.
Resource Sharing: Resources like code and data are shared between threads, thus allowing a
multithreaded application to have several threads of activity within the same address space.
Increased Concurrency: Threads may be running parallelly on different processors, increasing
concurrency in a multiprocessor machine.
Lesser Cost: It costs less to create and context-switch threads than processes.
Lesser Context-Switch Time: Threads take lesser context-switch time than processes.
Disadvantages of Threading
Complexity: Threading can make programs more complicated to write and debug because threads need
to synchronize their actions to avoid conflicts.
Resource Overhead: Each thread consumes memory and processing power, so having too many threads
can slow down a program and use up system resources.
Difficulty in Optimization: It can be challenging to optimize threaded programs for different hardware
configurations, as thread performance can vary based on the number of cores and other factors.
Debugging Challenges: Identifying and fixing issues in threaded programs can be more difficult
compared to single-threaded programs, making troubleshooting complex.
Context switch
Context switch time is less. Context switch time is more.
time
Creation and User-level threads can be created and Kernel-level level threads take more time
Management managed more quickly. to create and manage.
Any operating system can support user- Kernel-level threads are operating
Operating System
level threads. system-specific.
Example POSIX threads, Mach C-Threads. Java threads, POSIX threads on Linux.
Resource Limited access to system resources, It can access to the system-level features
utilization cannot directly perform I/O operations. like I/O operations.
User-level threads are more portable Less portable due to dependence on OS-
Portability
than kernel-level threads. specific kernel implementations.
Multitasking operating system is an operating system that gives you the perception of two or more
tasks/jobs/processes running simultaneously. It does this by dividing system resources amongst these
tasks/jobs/processes and switching between the tasks/jobs/processes while they are executing over and over
again. The CPU processes only one task at a time, but in Multitasking the switching is so fast that it looks like
the CPU is executing multiple processes simultaneously. They can support either preemptive multitasking, where
the OS doles out time to applications (virtually all modern OSes) or cooperative multitasking, where the OS waits
for the program to give back control (Windows 3.x, Mac OS 9 and earlier), leading to hangs and crashes. Also
known as Timesharing, multitasking is a logical extension of multiprogramming.
Multitasking Programming has Two Types:
1. Process-based Multitasking
2. Thread-based Multitasking
Process-Based Multitasking Thread-Based Multitasking
Many operating systems support kernel thread and user thread in a combined way. Example of such system is
Solaris. Multi threading model are of three types.
Many to many model.
Many to one model.
one to one model.
Thread Libraries:
A thread library provides the programmer with an API for creating and managing threads. There are two primary
ways of implementing a thread library. The first approach is to provide a library entirely in user space with no
kernel support. All code and data structures for the library exist in user space. This means that invoking a function
in the library results in a local function call in user space and not a system call. The second approach is to
implement a kernel-level library supported directly by the operating system. In this case, code and data structures
for the library exist in kernel space. Invoking a function in the API for the library typically results in a system call
to the kernel.
Three main thread libraries are in use today: POSIX Pthreads, Windows, and Java. Pthreads, the threads extension
of the POSIX standard, may be provided as either a user-level or a kernel-level library. The Windows thread library
is a kernel-level library available on Windows systems. The Java thread API allows threads to be created and
managed directly in Java programs.
Advantages of Multithreading in OS:
Minimize the time of context switching- Context Switching is used for storing the context or state of a
process so that it can be reloaded when required.
By using threads, it provides concurrency within a process- Concurrency is the execution of multiple
instruction sequences at the same time.
Creating and context switching is economical – Thread switching is very efficient because it involves
switching out only identities and resources such as the program counter, registers, and stack pointers.
Allows greater utilization of multiprocessor architecture
Disadvantages of Multithreading in OS:
A multithreading system operates without interruptions.
The code might become more intricate to comprehend.
The costs associated with handling various threads could be excessive for straightforward tasks.
Identifying and resolving problems may become more demanding due to the intricate nature of the code.
Remote Procedure Call (RPC) is a powerful technique for constructing distributed, client-server based
applications. It is based on extending the conventional local procedure calling so that the called procedure does
not exist in the same address space as the calling procedure. The two processes may be on the same system, or
they may be on different systems with a network connecting them.
What is Remote Procedure Call (RPC)?
Remote Procedure Call (RPC) is a type of technology used in computing to enable a program to request a service
from software located on another computer in a network without needing to understand the network’s details.
RPC abstracts the complexities of the network by allowing the developer to think in terms of function calls rather
than network details, facilitating the process of making a piece of software distributed across different systems.
RPC works by allowing one program (a client) to directly call procedures (functions) on another machine (the
server). The client makes a procedure call that appears to be local but is run on a remote machine. When an RPC
is made, the calling arguments are packaged and transmitted across the network to the server. The server
unpacks the arguments, performs the desired procedure, and sends the results back to the client.
Working of a RPC
1. A client invokes a client stub procedure, passing parameters in the usual way. The client stub resides within
the client’s own address space.
2. The client stub marshalls(pack) the parameters into a message. Marshalling includes converting the
representation of the parameters into a standard format, and copying each parameter into the message.
3. The client stub passes the message to the transport layer, which sends it to the remote server machine. On
the server, the transport layer passes the message to a server stub, which demarshalls(unpack) the parameters
and calls the desired server routine using the regular procedure call mechanism.
4. When the server procedure completes, it returns to the server stub (e.g., via a normal procedure call return),
which marshalls the return values into a message.
5. The server stub then hands the message to the transport layer. The transport layer sends the result message
back to the client transport layer, which hands the message back to the client stub.
6. The client stub demarshalls the return parameters and execution returns to the caller.
How to Make a Remote Procedure Call?
The calling environment is suspended, procedure parameters are transferred across the network to the
environment where the procedure is to execute, and the procedure is executed there. When the procedure
finishes and produces its results, its results are transferred back to the calling environment, where execution
resumes as if returning from a regular procedure call.
Note : RPC is especially well suited for client-server (e.g. query-response) interaction in which the flow of control
alternates between the caller and callee. Conceptually, the client and server do not both execute at the same
time. Instead, the thread of execution jumps from the caller to the callee and then back again.
Types of RPC
Callback RPC: Callback RPC allows processes to act as both clients and servers. It helps with remote
processing of interactive applications. The server gets a handle to the client, and the client waits during
the callback. This type of RPC manages callback deadlocks and enables peer-to-peer communication
between processes.
Broadcast RPC: In Broadcast RPC, a client’s request is sent to all servers on the network that can handle
it. This type of RPC lets you specify that a client’s message should be broadcast. You can set up
special broadcast ports. Broadcast RPC helps reduce the load on the network.
Batch-mode RPC: Batch-mode RPC collects multiple RPC requests on the client side and sends them to
the server in one batch. This reduces the overhead of sending many separate requests. Batch-mode RPC
works best for applications that don’t need to make calls very often. It requires a reliable way to send
data.
What Does RPC do?
RPC stands for Remote Procedure Call. It lets a program on one computer use code on another computer as if it
were on the same computer. When a program with RPC is made ready to run, it includes a helper part called
a stub. This stub acts like the remote code. When the program runs and tries to use the remote code, the stub
gets this request. It then sends it to another helper program on the same computer. The first time this happens,
the helper program asks a special computer where to find the remote code.
The helper program then sends a message over the internet to the other computer, asking it to run the remote
code. The other computer also has helper programs that work with the remote code. When the remote code is
done, it sends the results back the same way. This whole process makes it seem like the remote code is running
on the local computer, even though it’s actually running somewhere else.
Issues of the RPC
RPC Runtime: RPC run-time system is a library of routines and a set of services that handle the network
communications that underlie the RPC mechanism. In the course of an RPC call, client-side and server-side run-
time systems’ code handle binding, establish communications over an appropriate protocol, pass call data
between the client and server, and handle communications errors.
Stub: The function of the stub is to provide transparency to the programmer-written application code. On the
client side, the stub handles the interface between the client’s local procedure call and the run-time system,
marshalling and unmarshalling data, invoking the RPC run-time protocol, and if requested, carrying out some of
the binding steps.
On the server side, the stub provides a similar interface between the run-time system and the local manager
procedures that are executed by the server.
Binding: The most flexible solution is to use dynamic binding and find the server at run time when the RPC is first
made. The first time the client stub is invoked, it contacts a name server to determine the transport address at
which the server resides. Binding consists of two parts
Naming: A Server having a service to offer exports an interface for it. Exporting an interface registers it
with the system so that clients can use it.
Locating: A Client must import an (exported) interface before communication can begin.
The call semantics associated with RPC
Retry Request Message: Whether to retry sending a request message when a server has failed or the
receiver didn’t receive the message.
Duplicate Filtering: Remove the duplicate server requests.
Retransmission of Results: To resend lost messages without re-executing the operations at the server
side.
Advantages
Easy Communication: RPC lets clients talk to servers using normal procedure calls in high-level
programming languages. This makes it simple for programmers to work with.
Hidden Complexity: RPC hides the details of how messages are sent between computers. This means
programmers don’t need to worry about the underlying network communication.
Flexibility: RPC can be used in both local and distributed environments. This makes it versatile for
different types of applications.
Disadvantages
Limited Parameter Passing: RPC can only pass parameters by value. It can’t pass pointers, which limits
what can be sent between computers.
Slower Than Local Calls: Remote procedure calls take longer than local procedure calls because they
involve network communication.
Vulnerable to Failures: RPC depends on network connections, other machines, and separate processes.
This makes it more likely to fail than local procedure calls.
RPC vs REST
RPC and REST are two ways to make computer programs talk to each other over the internet. They’re different,
but both are useful. RPC is good for some things, and REST is good for others. Some companies need RPC, while
others prefer REST. Sometimes, developers use both RPC and REST in the same project, but not in the same part
of the program. RPC is an old idea, but new versions like gRPC and DRPC are making it popular again. Developers
are still using and improving these new types of RPC.
It’s hard to say which one is better – RPC or REST. They’re both good when used the right way. The best choice
depends on what you’re trying to do with your program.
3.8. Scheduling
3.9. Deadlock
Chapter-4
Memory Management