Professional Documents
Culture Documents
os_ansh
os_ansh
os_ansh
Ansh Kasaudhan
2023-2024
—
BCS-451
—
Under the Guidance of
Mr. Deepak Singh Sir
2
INTRODUCTION
PAGE 2
3
Index
S. Name of Date of Date of Page Teacher’s
No Program Conduction checking No. Sign
1. (i) To understand OS functionalities like
system configuration, device manager,
and group policy.
(ii) Understand the minimum
requirements of different Operating
System like Window XP, Window 8.1
and higher, Linux, Unix, Mac OS.
2. Basics of UNIX/ DOS Commands.
3. Implementation of CPU Scheduling.
(i) FCFS, (ii) SJF
4. Implementation of CPU Scheduling.
( i ) Shortest Remaining Time First
(ii) Priority based
5. Implementation of CPU Scheduling:
(i) Round Robin (ii) Longest Job First.
6. Implementation of Process and thread
(Life cycle of process): (i) Process
creation and Termination; (ii) Thread
creation and Termination
7. Producer-Consumer Problem using
Semaphores and Reader Writer Problem
8. Simulate algorithm for deadlock
prevention and detection
9. Simulate the algorithm for deadlock
avoidance and study about deadlock
recovery.
10. Simulate memory allocation methods:
(i) Best Fit, (ii) Worst Fit and (iii)
Next Fit
11. Simulate page replacement algorithms:
FIFO, LRU and Optimal.
12. Implementation of Disk Scheduling
using FCFS, SCAN and C-SCAN
algorithm
13. Implementation of Disk Scheduling
using LOOK, C-LOOK and SSTF
algorithm
4
Program 1
Aim: - (i) To understand OS functionalities like system configuration, device manager, and
group policy.
Theory: -
MSconfig
• Open Search in the Toolbar and type Run, or select Run from your Start Menu.
• Type ‘msconfig’ in the Run command and click OK.
General Tab
1. Normal Startup:
• Loads all device drivers and services.
2. Diagnostic Startup:
• Loads basic devices and services only, similar to Safe Mode.
3. Selective Startup:
• Allows the user to select which programs and services to load.
Boot Tab 5
1. Boot Options:
• Safe Boot: Boots Windows in Safe Mode with different sub-options:
o Minimal: Basic Safe Mode.
o Alternate Shell: Safe Mode with Command Prompt.
o Active Directory Repair: Used to repair the Active Directory server.
o Network: Safe Mode with networking.
• No GUI Boot: Boots without the Windows GUI (graphical user interface).
• Boot Log: Creates a file of the boot process.
• Base Video: Boots using basic video drivers.
• OS Boot Information: Displays drivers being loaded during boot.
• Timeout: Specifies the time to display the list of operating systems.
2. Advanced Options:
• Number of processors: Limits the number of processors to use.
• Maximum memory: Limits the amount of memory used.
• Debugging mode: Enables debugging.
Tools Tab
• Provides quick access to various system tools and utilities, such as:
• System Information
• Event Viewer
• Performance Monitor
• Command Prompt
• Registry Editor
• Task Manager
These features of msconfig make it a powerful utility for managing the boot process and troubleshooting
startup issues in Windows.
Gpedit.msc
The Group Policy Editor is a Windows administration tool that allows users to configure many important
settings on their computers or networks. Administrators can configure password requirements, startup
programs, and define what applications or settings users can change.
6
Steps to open Group policy editor
Option 1: Open Local Group Policy Editor in Run
• Open Search in the Toolbar and type Run, or select Run from your Start Menu.
• Type ‘gpedit.msc’ in the Run command and click OK.
Option 5: Open Local Group Policy Editor in Start Menu Control Panel
There are hundreds of different settings like this in Group Policy Editor.
• Computer Configuration: These policies apply to the local computer, and do not change per user.
• User Configuration: These policies apply to users on the local machine, and will apply to any new
users in the future, on this local computer.
• Those two main categories are further broken down into sub-categories:
• Software Settings: Software settings contain software specific group policies: this setting is empty by
default.
7
Regedit
The Windows Registry Editor (regedit) is a graphical tool in the Microsoft Windows operating system (OS)
that enables authorized users to view the Windows registry and make changes.
The Windows registry, also known as the registry, is a hierarchical database that stores the configuration
settings required for a computer to operate efficiently. This information includes basic boot-up functions, user
profile information, startup options, installed applications and drivers, system hardware information and
specific design settings.
• Open Search in the Toolbar and type Run, or select Run from your Start Menu.
• Type ‘regedit’ in the Run command and click OK.
• Hierarchical Structure: The registry is organized in a tree-like structure with keys and subkeys,
similar to folders and files in a filesystem. The main root keys include:
o HKEY_CLASSES_ROOT (HKCR): Contains information about registered applications,
file associations, and COM objects.
o HKEY_CURRENT_USER (HKCU): Stores settings specific to the current user.
o HKEY_LOCAL_MACHINE (HKLM): Contains settings that apply to the local
machine, regardless of the user.
o HKEY_USERS (HKU): Contains user-specific settings for all users on the system.
o
o HKEY_CURRENT_CONFIG (HKCC): Contains hardware profile information used
8 at
system startup.
• Keys: Like folders in the file system, they can contain subkeys and values.
• Values: Come in several types, including:
o String (REG_SZ): A fixed-length text string.
o Binary (REG_BINARY): Raw binary data.
o DWORD (REG_DWORD): A 32-bit number.
o QWORD (REG_QWORD): A 64-bit number.
o Multi-String (REG_MULTI_SZ): An array of strings.
o Expandable String (REG_EXPAND_SZ): A string that contains environment variables.
• Users can add, modify, delete, and rename keys and values.
• Find: Allows users to search for specific keys, values, or data within the registry.
• Find Next: Continues the search from the current location.
• Export: Allows users to save a part or the entirety of the registry to a file, which can be used for
backup purposes or for transferring settings to another machine.
• Import: Enables users to load a previously exported registry file, merging its contents with the
current registry.
5. Permissions:
• Users can set permissions on keys to control access, allowing or denying specific users or groups
the ability to read or modify certain keys.
6. Favorites:
• Users can add frequently accessed keys to a favorites list for quick access.
7. View Options:
• Split View: Users can split the view to see different parts of the registry simultaneously.
• Status Bar: Shows the path of the selected key and the number of subkeys and values it contains.
9
Aim: - (ii) Understand the minimum requirements of different Operating System like
Window XP, Window 8.1 and higher, Linux, Unix, Mac OS.
Theory: -This section aims to outline and compare the minimum hardware and software
requirements for various popular operating systems, including Windows XP, Windows 8.1
and higher, Linux, Unix, and Mac OS. Understanding these requirements is crucial for
system compatibility and optimal performance.
Processor (CPU): The central processing unit's speed and capabilities, measured in gigahertz
(GHz), affect the system's ability to execute tasks. Different OS versions have varying minimum CPU
requirements to ensure smooth operation.
Memory (RAM): Random-access memory is critical for multitasking and running applications.
Higher RAM allows for better performance and handling of more demanding software.
Storage (Hard Drive/SSD): The amount of available storage space is necessary for the OS
installation and for storing applications and files. Solid-state drives (SSDs) offer faster data access
speeds compared to traditional hard drives (HDDs).
Graphics Card: A dedicated or integrated graphics processing unit (GPU) is essential for
rendering images, videos, and graphical interfaces. Some OS require specific graphics capabilities to
support advanced features.
Other Peripherals: Input and output devices like keyboards, mice, monitors, and printers may
have specific requirements based on the OS.
OS Kernel: The core component of the operating system that manages hardware resources and
facilitates interactions between hardware and software.
Drivers: Software that allows the OS to communicate with hardware devices such as printers,
graphics cards, and network adapters.
Utilities: Essential tools and programs that come with the OS to perform system maintenance
and management tasks.
Libraries: Pre-compiled code modules that applications can use to perform common functions
without having to write code from scratch. These are often required for running certain applications.
Compatibility: Specific software versions or features that must be present for the OS to function
correctly with other installed applications.
Security Software: Built-in or additional antivirus and firewall programs to protect the system
from malware and unauthorized access.
Program 2
Aim: - Basics of UNIX/ DOS Commands.
Theory: -
MS Dos Commands
MS-DOS is a text-based system of Microsoft Operating System; The users interact with the
computer by typing text-based commands rather than a Graphical User Interface. These
commands allow users to perform various tasks, such as copying, deleting, or moving files,
and managing programs.
File Management: MS Dos commands enable users to navigate through directories and
create, delete, or copy files, enabling efficient file management.
System Configuration: Users can configure system settings, manage drives, and analyze
hardware issues using MS Dos commands, providing a robust toolkit for system
customization.
Program Execution: MS Dos for commands facilitate the execution of programs and scripts,
offering a streamlined approach to launching applications without the need for graphical
interfaces.
1. Select the Start Menu (the Windows icon) in the taskbar, or press the Windows key.
2. Type cmd.
3. Select Command Prompt from the list.
If you're using the latest version of Windows 11, Command Prompt will open
within Terminal.
13
Program 3
Aim - Implementation of CPU Scheduling. (i) FCFS, (ii) SJF
Theory: -
FCFS Algorithm
Algorithm: -
1. Initialize Variables: Declare arrays for process IDs, burst times, arrival times, completion times, turn-
around times, and waiting times. Initialize variables for total waiting time and total turn-around time.
2. Input Number of Processes: Ask the user for the number of processes (n) and store the input.
3. Input Burst Time and Arrival Time: For each process, prompt the user to input the burst time and
arrival time.
4. Calculate CT, TAT, WT:
• Set current_time to 0.
• For each process:
o If current_time is less than the arrival time, set it to the arrival time.
o Calculate completion time (ct[i]) as current_time + bt[i].
o Update current_time to ct[i].
o Calculate turn-around time (tat[i]) as ct[i] - at[i].
o Calculate waiting time (wt[i]) as tat[i] - bt[i].
5. Display Process Details: Print the process ID, burst time, arrival time, completion time, turn-around
time, and waiting time for each process.
6. Calculate and Display Averages: Calculate average waiting time (avg_wt) and average turn-around
time (avg_tat). Print these averages.
Code: -
#include <stdio.h>
// Function to find the completion time, turn around time and waiting time for all
processes
void findCT_TAT_WT(int processes[], int n, int bt[], int at[], int ct[], int tat[], int wt[]) {
int current_time = 0;
// Function to find completion time, turn around time and waiting time for all processes
findCT_TAT_WT(processes, n, bt, at, ct, tat, wt);
SJF Algorithm
DESCRIPTION: -The job which has shortest burst time is executed first.
Algorithm: -
1) Initialize Variables: Declare arrays for process IDs, burst times, arrival times, completion times, turn-
around times, and waiting times. Initialize variables for total waiting time and total turn-around time.
2) Input Number of Processes: Ask the user for the number of processes (n) and store the input.
3) Input Burst Time and Arrival Time: For each process, prompt the user to input the burst time.
4) Sort Processes by Burst Time: Sort the processes based on their burst times in ascending order.
5) Calculate CT, TAT, WT:
• Set current_time to 0.
• For each process in sorted order:
o Calculate completion time (ct[i]) as current_time + bt[i].
o Update current_time to ct[i].
o Calculate turn-around time (tat[i]) as ct[i] - at[i].
o Calculate waiting time (wt[i]) as tat[i] - bt[i].
6) Display Process Details: Print the process ID, burst time, arrival time, completion time, turn-around time,
and waiting time for each process.
7) Calculate and Display Averages: Calculate average waiting time (avg_wt) and average turn-around time
(avg_tat). Print these averages.
16
Code: -
#include <stdio.h>
// Function to find completion time, turn around time and waiting time for all processes
void findCT_TAT_WT(int processes[], int n, int bt[], int at[], int ct[], int tat[], int wt[]) {
int current_time = 0;
// Find completion time, turn around time and waiting time for all processes
findCT_TAT_WT(processes, n, bt, at, ct, tat, wt);
// Driver code
int main() {
int n;
int processes[n];
int burst_time[n];
int arrival_time[n];
Output: -
19
Program 4
Aim: - Implementation of CPU Scheduling. (i) Shortest Remaining Time First
(ii) Priority based
Theory: -
SRTF Algorithm
DESCRIPTION: -The process that have shortest remaining time is executed first.
Algorithm: -
1. Initialize Variables:
• Declare arrays for process IDs, burst times, arrival times, completion times, turn-around times,
and waiting times.
• Initialize remaining time for each process, current time, and completed process count.
2. Input Number of Processes:
• Prompt user for number of processes (n) and store it.
3. Input Burst Time and Arrival Time for Each Process:
• For each process, get burst time and arrival time from user.
4. Find Shortest Remaining Job:
• Create a function to find the process with shortest remaining time among arrived and
uncompleted processes.
5. Calculate Completion Time, Turn-Around Time, and Waiting Time:
• Loop until all processes are completed:
• Find process with shortest remaining time.
• If process found:
o Reduce its remaining time by 1.
o Update current time.
o If remaining time becomes 0, calculate completion time, turn-around time, and waiting
time.
6. Display Process Details:
• Print process ID, burst time, arrival time, completion time, turn-around time, and waiting time
for each process.
7. Calculate and Display Averages:
• Calculate average waiting time and average turn-around time.
• Print these averages.
Code: -
#include <stdio.h>
#include <limits.h>
return shortestIndex;
}
// Function to find completion time, turn-around time and waiting time for all processes
void findCT_TAT_WT(int processes[], int n, int bt[], int at[], int ct[], int tat[], int wt[]) {
int rt[n];
int currentTime = 0;
int completed = 0;
while (completed != n) {
int shortestJobIndex = findShortestJob(bt, at, rt, n, currentTime);
if (shortestJobIndex == -1) {
currentTime++;
continue;
}
// If a process is completed
if (rt[shortestJobIndex] == 0) {
completed++;
// Driver code
int main() {
int n;
int processes[n];
int burst_time[n];
int arrival_time[n];
Priority Algorithm
DESCRIPTION: - The process which ha highest priority (lowest number or vice versa) is
executed first.
Algorithm: -
1. Initialize Variables:
• Declare arrays for process IDs, burst times, arrival times, priorities, completion times, turn-
around times, and waiting times.
2. Input Number of Processes:
• Prompt the user for the number of processes (n) and store the input.
3. Input Process Details:
• For each process:
o Prompt the user to input burst time, arrival time, and priority.
4. Sort Processes by Priority:
• Sort the processes based on their priorities in ascending order.
5. Calculate Completion Time, Turn-Around Time, and Waiting Time:
• Initialize current time to 0.
• Loop through the sorted processes:
o Calculate completion time, turn-around time, and waiting time for each process.
6. Display Process Details:
• Print process ID, burst time, arrival time, priority, completion time, turn-around time, and
waiting time for each process.
7. Calculate and Display Averages:
• Calculate average waiting time and average turn-around time.
• Print these averages.
Code: - 23
#include <stdio.h>
#include <stdbool.h>
temp = bt[j];
bt[j] = bt[j + 1];
bt[j + 1] = temp;
temp = at[j];
at[j] = at[j + 1];
at[j + 1] = temp;
temp = priority[j];
priority[j] = priority[j + 1];
priority[j + 1] = temp;
}
}
}
}
// Function to find completion time, turn-around time, and waiting time for all processes
void findCT_TAT_WT(int processes[], int n, int bt[], int at[], int priority[], int ct[], int tat[], int wt[]) {
int currentTime = 0;
// Driver code
int main() {
int n;
int processes[n];
int burst_time[n];
int arrival_time[n];
int priority[n];
// Input burst time, arrival time, and priority for each process
for (int i = 0; i < n; i++) {
processes[i] = i + 1; // Process IDs
printf("Enter burst time for process %d: ", i + 1);
scanf("%d", &burst_time[i]);
printf("Enter arrival time for process %d: ", i + 1);
scanf("%d", &arrival_time[i]);
printf("Enter priority for process %d: ", i + 1);
scanf("%d", &priority[i]);
}
// Calculate average waiting time and average turn-around time 25
findavgTime(processes, n, burst_time, arrival_time, priority);
return 0;
}
Output: -
26
Program 5
Aim: - Implementation of CPU Scheduling. (i) Round Robin (ii) Longest Job First.
Theory: -
Round Robin Algorithm
DESCRIPTION: - The process that arrives first is executed first with a proper Time Quantum.
Algorithm: -
1. Initialize Variables:
• Declare arrays for process IDs, burst times, arrival times, completion times, turn-around times,
and waiting times.
• Initialize variables for quantum (time slice), current time, and completed process count.
2. Input Number of Processes:
• Prompt the user for the number of processes (n) and store it.
3. Input Burst Time and Arrival Time for Each Process:
• For each process, get burst time and arrival time from the user.
4. Round Robin Execution:
• Set up a queue to manage the processes awaiting execution.
• Initialize a timer to track elapsed time.
• Iterate until all processes are completed:
o Select a process from the front of the queue.
o Execute the process for a fixed quantum time.
o Update the current time and reduce the burst time of the process accordingly.
o If the process completes within the quantum:
▪ Calculate its completion time, turn-around time, and waiting time.
▪ Move it to the completed queue.
o If the process does not complete within the quantum:
▪ Move it to the end of the queue to allow other processes to execute.
o Repeat until all processes are executed.
5. Display Process Details:
• Print process ID, burst time, arrival time, completion time, turn-around time, and waiting time
for each process.
6. Calculate and Display Averages:
• Calculate the average waiting time and average turn-around time based on completed processes.
• Print these averages to summarize the performance of the Round Robin scheduling algorithm.
Code: -
#include <stdio.h>
// Function to find completion time, turn-around time, and waiting time for all processes
void findCT_TAT_WT(int processes[], int n, int bt[], int at[], int ct[], int tat[], int wt[], int quantum) {
int rt[n];
while (completed != n) {
int done = 1;
if (done == 1) {
break;
}
}
}
// Find completion time, turn-around time, and waiting time for all processes
findCT_TAT_WT(processes, n, bt, at, ct, tat, wt, quantum);
// Driver code
int main() {
int n, quantum;
int processes[n];
int burst_time[n];
int arrival_time[n];
DESCRIPTION: - The job which has longest burst time is executed first.
Algorithm: -
1. Initialize Variables:
• Declare arrays for process IDs, burst times, arrival times, completion times, turn-around times,
and waiting times.
• Initialize variables for current time, completed process count, and any other necessary tracking
variables.
2. Input Number of Processes:
• Prompt the user for the number of processes (n) and store it.
3. Input Burst Time and Arrival Time for Each Process:
• For each process, get burst time and arrival time from the user.
4. Sort Processes by Burst Time (Longest Job First):
• Implement a sorting function to arrange processes in descending order based on their burst times.
5. Calculate Completion Time, Turn-Around Time, and Waiting Time:
• Initialize a timer for tracking current time.
• Iterate through the sorted list of processes:
o Select the process with the longest burst time.
o Execute the process to completion.
o Update current time and calculate its completion time, turn-around time, and waiting time.
o Move to the next process and repeat until all processes are completed.
6. Display Process Details:
• Print process ID, burst time, arrival time, completion time, turn-around time, and waiting time
for each process.
7. Calculate and Display Averages:
• Calculate the average waiting time and average turn-around time based on completed processes.
• Print these averages to summarize the performance of the LJF scheduling algorithm.
Code: -
#include <stdio.h>
#include <stdbool.h>
temp = bt[j];
bt[j] = bt[j + 1];
bt[j + 1] = temp;
temp = at[j];
at[j] = at[j + 1];
at[j + 1] = temp;
}
}
} 30
}
// Function to find completion time, turn-around time, and waiting time for all processes
void findCT_TAT_WT(int processes[], int n, int bt[], int at[], int ct[], int tat[], int wt[]) {
int currentTime = 0;
// Find completion time, turn-around time, and waiting time for all processes
findCT_TAT_WT(processes, n, bt, at, ct, tat, wt);
// Driver code
int main() {
int n;
int processes[n];
int burst_time[n];
int arrival_time[n];
Output: -
32
Program 6
Aim: - Implementation of Process and thread (Life cycle of process): (i) Process
creation and Termination; (ii) Thread creation and Termination.
Theory: -
Process creation and Termination
Algorithm: -
1. Create a Child Process:
• Use the fork() system call to create a new process.
• Upon successful creation, fork() returns a non-negative value (child PID) to the parent process
and 0 to the child process.
• If fork() fails, it returns a negative value indicating an error.
2. Child Process Execution:
• In the child process (identified by fork() returning 0), perform specific tasks unique to the child's
execution context.
• This may involve computations, I/O operations, or any other tasks required by the application.
3. Parent Process Handling:
• In the parent process, after fork() succeeds, it typically continues its own execution or waits for
the child process to complete using wait() or waitpid() system calls.
• wait() or waitpid() allows the parent to synchronize with the termination of the child process and
retrieve its termination status.
4. Termination of Processes:
• Both parent and child processes may terminate explicitly using exit() system call, indicating
successful completion or abnormal termination with an exit status.
• The termination status can be retrieved by the parent process using wait() or waitpid().
5. Cleanup and Resource Release:
• After the child process terminates, the parent process should release any resources associated with
the child process and continue its execution or terminate based on application logic.
Code: -
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t pid;
return 0;
}
Output: -
34
Thread creation and Termination
DESCRIPTION: - Threads are lightweight processes within a process that share resources
such as memory and file descriptors. Thread creation and termination involve spawning new
threads, executing concurrent tasks within the same process, and managing their life cycle
until completion.
Algorithm: -
1. Create a Thread:
• Use the pthread_create() function to create a new thread within the current process.
• Provide the necessary arguments such as thread attributes and a function pointer to the function
that the thread will execute.
2. Thread Function Execution:
• Define a function that will be executed by the newly created thread (pthread_create() takes this
function pointer as an argument).
• This function performs the specific tasks or computations that the thread is responsible for.
3. Main Thread Handling:
• In the main thread of execution, after pthread_create() successfully creates a thread, it can
continue its own tasks or synchronize with the newly created thread using pthread_join().
4. Wait for Thread Completion:
• Use pthread_join() to wait for the thread to complete its execution. This function blocks the
main thread until the specified thread terminates.
• pthread_join() also optionally retrieves the exit status of the thread upon termination.
5. Thread Termination:
• Inside the thread function, terminate the thread's execution by calling pthread_exit() with a
return value.
• The return value of pthread_exit() can be retrieved by the thread that joined it using
pthread_join().
6. Cleanup and Resource Management:
• After a thread completes its execution, any resources it acquired (e.g., allocated memory) should
be properly released to avoid memory leaks or resource contention.
Code: -
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
int main() {
pthread_t thread;
int ret;
printf("Main thread started.\n");
// Create thread
ret = pthread_create(&thread, NULL, thread_function, NULL);
if (ret) {
fprintf(stderr, "Error: pthread_create() failed\n"); 35
return 1;
}
return 0;
}
Output: -
36
Program 7
Aim: - Implementation of Producer-Consumer Problem using Semaphores and
Reader Writer Problem
Theory: -
Producer-Consumer Problem
Algorithm: -
1. Initialize Semaphores and Shared Buffer:
• Use semaphores to manage the synchronization:
o empty semaphore initialized to the buffer size (number of empty slots).
o full semaphore initialized to 0 (no items in the buffer initially).
o mutex semaphore for mutual exclusion.
2. Producer Thread:
• Wait on empty (decrement if a slot is available).
• Wait on mutex to enter the critical section.
• Add an item to the buffer.
• Signal (increment) mutex.
• Signal full (indicate an item is available).
3. Consumer Thread:
• Wait on full (decrement if an item is available).
• Wait on mutex to enter the critical section.
• Remove an item from the buffer.
• Signal (increment) mutex.
• Signal empty (indicate an empty slot is available).
Code: -
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int in = 0, out = 0;
sem_t empty, full, mutex;
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
printf("Produced: %d\n", item);
sleep(1);
}
}
item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
printf("Consumed: %d\n", item);
sleep(1);
}
}
int main() {
pthread_t prod_tid, cons_tid;
// Initialize semaphores
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
// Destroy semaphores
sem_destroy(&empty);
sem_destroy(&full);
sem_destroy(&mutex);
return 0;
}
38
Output: -
DESCRIPTION: - The Reader-Writer problem ensures that multiple readers can access the
shared resource simultaneously, but writers require exclusive access to the resource.
Semaphores are used to manage access and maintain the synchronization between readers and
writers.
Algorithm: -
1. Initialize Semaphores and Variables:
• rw_mutex semaphore for writer access (initialized to 1).
• mutex semaphore for reader count access (initialized to 1).
• read_count to track the number of readers.
2. Reader Thread:
• Wait on mutex to enter the critical section to update read_count.
• If the reader is the first one, wait on rw_mutex to block writers.
• Increment read_count.
• Signal mutex to exit the critical section.
• Read the shared resource.
• Wait on mutex to enter the critical section to update read_count.
• If the reader is the last one, signal rw_mutex to allow writers.
• Decrement read_count.
• Signal mutex to exit the critical section.
3. Writer Thread:
• Wait on rw_mutex to enter the critical section (block other readers and writers).
• Write to the shared resource.
• Signal rw_mutex to exit the critical section (allow readers and writers).
Code: - 39
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
// Reading section
printf("Reader is reading\n");
sleep(1);
sleep(1);
}
}
// Writing section
printf("Writer is writing\n");
sleep(1);
int main() {
pthread_t rtid1, rtid2, wtid;
// Initialize semaphores
sem_init(&rw_mutex, 0, 1);
sem_init(&mutex, 0, 1);
// Create reader and writer threads 40
pthread_create(&rtid1, NULL, reader, NULL);
pthread_create(&rtid2, NULL, reader, NULL);
pthread_create(&wtid, NULL, writer, NULL);
// Destroy semaphores
sem_destroy(&rw_mutex);
sem_destroy(&mutex);
return 0;
}
Output: -