Operating System File
Operating System File
1.OBJECTIVE:-
The objective of this experiment is to demonstrate basic file handling operations in C, such as
opening, reading, writing, and closing files. The experiment will cover:
1.Creating and writing data to a file.
2.Reading data from a file.
3.Appending data to an existing file.
4.Understanding the use of file pointers and the different file modes in C.
2.SYSTEM REQUIREMENTS:-
Hardware Requirements:
1.Any standard computer with a processor capable of running C programs.
2.Minimum 1GB RAM for basic file operations.
Software Requirements:
1.Operating System: Windows/Linux/macOS (any system with C compiler support).
2.Compiler: GCC, Clang, or any C compiler (support for file I/O operations).
3.Development Environment: Any IDE or text editor (VSCode, Code::Blocks, etc.).
3.FILE HANDLING:-
In C programming, file handling allows a program to read from and write to files, providing
persistent storage for data. Files are opened using the fopen() function and can be handled using
different modes such as:
1."r": Open for reading (file must exist).
2."w": Open for writing (creates a new file or overwrites an existing file).
3."a": Open for appending (writes data at the end of the file).
4."rb", "wb", "ab": Binary modes for reading, writing, and appending binary data.
The key operations involved in file handling include:
1.Opening a file with fopen().
2.Reading from a file using functions like fgetc(), fgets(), or fread().
3.Writing to a file with fputc(), fputs(), or fwrite().
4.Closing the file with fclose() to free resources.
4.PROGRAM FOR FILE HANDLING:-
// C program to Open a File,
// Write in it, And Close the File
#include <stdio.h>
#include <string.h>
int main()
{
// Declare the file pointer
FILE* filePointer;
// Get the data to be written in file
char dataToBeWritten[50] = "GeeksforGeeks-A Computer "
"Science Portal for Geeks";
// Open the existing file GfgTest.c using fopen()
// in write mode using "w" attribute
filePointer = fopen("GfgTest.c", "w");
// Check if this filePointer is null
// which maybe if the file does not exist
if (filePointer == NULL) {
printf("GfgTest.c file failed to open.");
}
else {
printf("The file is now opened.\n");
// Write the dataToBeWritten into the file
if (strlen(dataToBeWritten) > 0) {
// writing in the file using fputs()
fputs(dataToBeWritten, filePointer);
fputs("\n", filePointer);
}
// Closing the file using fclose()
fclose(filePointer);
printf("Data successfully written in file "
"GfgTest.c\n");
printf("The file is now closed.");
}
return 0;
}
5.OUTPUT:-
6.RESULT:-
When the program is executed, it performs the following operations:
1.It creates or overwrites the file example.txt with the line "This is a sample text written to the file."
2.It reads the contents of the file and prints it to the console:
EXPERIMENT –2
1.OBJECTIVE:-
To simulate the Dining Philosophers Problem using threads mutexes, demonstrating how to manage
concurrent access to shared resources and prevent issues like deadlock and starvation.
2.SYSTEM REQUIREMENTS:-
Hardware Requirements:
The Dining Philosophers Problem is a classic synchronization problem where multiple philosophers
sit around a table, thinking and eating. To eat, each philosopher needs two forks—one on the left
and one on the right. The challenge is to ensure that no philosopher experiences deadlock (waiting
forever for forks), starvation (being indefinitely blocked from eating), or race conditions
(conflicting access to forks)..
The main issues involved are:
• Deadlock: Philosophers may get stuck waiting for each other to release forks.
• Starvation: Some philosophers may never get a chance to eat.
• Synchronization: Proper management of resources (forks) is needed to avoid these problems.
In this experiment, we simulate the problem using threads and mutexes to synchronize access to
shared resources (forks), preventing deadlock and ensuring fair resource allocation.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM_PHILOSOPHERS 5
#define NUM_CHOPSTICKS 5
int main()
{
// Define counter var i and status_message
int i, status_message;
void *msg;
// Wait for all philosophers threads to complete executing (finish dining) before closing the
program
for (i = 1; i <= NUM_PHILOSOPHERS; i++)
{
status_message = pthread_join(philosopher[i], &msg);
if (status_message != 0)
{
printf("\n Thread join failed \n");
exit(1);
}
}
6.RESULT:-
The objective of the Producer-Consumer Problem experiment is to synchronize the producer and
consumer processes using semaphores and mutexes. This ensures safe access to the shared buffer,
preventing race conditions and deadlock.
2.REQUIREMENT:-
Buffer: A shared data structure (usually an array or queue) that stores the items produced by the
producer and consumed by the consumer.
Semaphores: Semaphores (or mutexes) are used for synchronization between the producer and
consumer:
Threads: The producer and consumer are typically implemented as separate threads to allow
concurrent execution.
Synchronization Mechanisms: The system must synchronize the producer and consumer to
avoid accessing the buffer simultaneously and manage buffer overflow/underflow situations
3.PRODUCER-CONSUMER PROBLEM:-
The Producer-Consumer Problem involves two primary tasks:
1.Producer: The producer generates data and places it into the buffer. It can only produce if
there is space available in the buffer.
2.Consumer: The consumer takes data from the buffer and processes it. It can only consume if
the buffer is not empty.
Key Concepts:
3.Synchronization: The producer and consumer must synchronize their actions to avoid issues
such as race conditions, where both might try to access the buffer at the same time.
4.Semaphore/Mutex Usage:
.The Empty semaphore ensures that the producer waits if the buffer is full (no empty slots).
.The Full semaphore ensures that the consumer waits if the buffer is empty (no items to
consume).
.The Mutex ensures that the producer and consumer cannot access the buffer simultaneously,
preventing race conditions.
1.Buffer Management: The shared buffer must be managed in such a way that the producer does
not overwrite an item before the consumer consumes it, and the consumer does not try to
consume an item that hasn't been produced yet.
5.OUTPUT:-
EXPERIMENT-4
1.OBJECTIVE:-
The aim of this experiment is to implement the First Come, First Serve (FCFS) scheduling
algorithm in C language to demonstrate how processes are scheduled in the order of their arrival.
The experiment will focus on calculating metrics such as waiting time, turnaround time, and
completion time.
2.REQUIREMENT:-
i. Programming Language: C
ii. Input: Arrival time and burst time (execution time) of processes.
iii. Output: Completion time, waiting time, and turnaround time for each process.
iv. Tools: A C compiler (e.g., GCC).
The First Come, First Serve (FCFS) algorithm is one of the simplest CPU scheduling
algorithms. In FCFS:
• The process that arrives first gets executed first.
• If two processes arrive at the same time, the one that appears first in the input list is executed
first.
• FCFS is a non-preemptive algorithm, meaning once a process starts execution, it will run to
completion without being interrupted.
Formula:
1.Waiting Time (WT) for a process is the total time it has been in the ready queue waiting for
CPU time.
WT=Start Time−Arrival Time
2.Turnaround Time (TAT) is the total time spent from the arrival of a process to its completion.
TAT=Completion Time−Arrival Time
3.Completion Time (CT) is the time at which the process finishes its execution.
CT=Start Time + Burst Time
6.RESULT:-
The First-Come-First-Served (FCFS) algorithm is a basic and fair scheduling approach but is not
optimal for performance, especially when there is a large difference in burst times of processes. It
can lead to high waiting times for shorter processes if long processes arrive first. However, it
remains widely used in simple systems and in scenarios where fairness and simplicity are more
important than optimal CPU utilization.
EXPERIMENT-5
1.OBJECTIVE:-
The aim of this experiment is to implement the Shortest Job First (SJF) scheduling algorithm in
C, which selects the process with the shortest burst time for execution. The goal is to calculate
and display the waiting time, turnaround time, and completion time for each process.
2.REQUIREMENTS:-
1. Programming Language: C
2. Input:
o Number of processes.
o Arrival time and burst time (execution time) of each process.
3. Output:
o Process ID, Arrival Time, Burst Time, Completion Time, Waiting Time, and
Turnaround Time for each process.
4. Tools: C compiler (e.g., GCC).
3.SJF ALGORITHM:-
The Shortest Job First (SJF) scheduling algorithm selects the process with the shortest burst time
for execution. If two processes have the same burst time, FCFS (First-Come-First-Serve) can be
used as a tie-breaker. SJF is considered optimal because it minimizes the average waiting time.
However, it requires knowing the burst times of processes in advance, which is not always
feasible.
Key Terminology:
1.Burst Time: The time required by a process for execution.
2.Waiting Time: The total time a process has spent waiting in the ready queue.
WT=Start Time−Arrival Time
3.Turnaround Time: The total time spent by the process from its arrival to its completion.
TAT=Completion Time−Arrival Time
4.Completion Time: The time at which the process finishes its execution.
The SJF algorithm is non-preemptive, meaning once a process starts executing, it runs to
completion without being interrupted.
6.RESULT:-
The First-Come-First-Served (FCFS) algorithm is a basic and fair scheduling approach but is not
optimal for performance, especially when there is a large difference in burst times of processes. It
can lead to high waiting times for shorter processes if long processes arrive first. However, it
remains widely used in simple systems and in scenarios where fairness and simplicity are more
important than optimal CPU utilization.
EXPRIMENT-6
1.OBJECTIVE:-
The aim of this experiment is to implement the Round Robin (RR) scheduling algorithm in C,
where processes are assigned a fixed time quantum for execution. The goal is to calculate and
display the waiting time, turnaround time, and completion time for each process.
2.REQUIREMENT:-
Programming Language: C
Input:
• Number of processes.
• Arrival time and burst time (execution time) for each process.
• Time quantum (time slice).
Output:
• Process ID, Arrival Time, Burst Time, Completion Time, Waiting Time, and Turnaround
Time for each process.
Tools: C compiler (e.g., GCC).
Round Robin is a CPU scheduling algorithm where each process is assigned a fixed time slot in a
cyclic way. It is basically the preemptive version of First come First Serve CPU Scheduling
algorithm.
1 . Round Robin CPU Algorithm generally focuses on Time Sharing technique.
2.The period of time for which a process or job is allowed to run in a
pre-emptive method is called time quantum.
3.Each process or job present in the ready queue is assigned the CPU for that time quantum, if
the execution of the process is completed during that time then the process will end else the
process will go back to the waiting table and wait for its next turn to complete the execution.
Key Metrics:
• Waiting Time (WT): The time a process spends waiting in the ready queue before it gets
the CPU.
WT=Turnaround Time−Burst Time
• Turnaround Time (TAT): The total time from the arrival of a process to its completion.
TAT=Completion Time−Arrival Time
• Completion Time (CT): The time at which the process finishes its execution.
int quant;
int main()
{
int n, i, j;
// Taking Input
printf("Enter the no. of processes :");
scanf("%d", &n);
struct P p[n];
printf("Enter the quantum \n");
scanf("%d", &quant);
printf("Enter the process numbers \n");
for (i = 0; i < n; i++)
scanf("%d", &(p[i].pos));
printf("Enter the Arrival time of processes \n");
for (i = 0; i < n; i++)
scanf("%d", &(p[i].AT));
// Declaring variables
int c = n, s[n][20];
float time = 0, mini = INT_MAX, b[n], a[n];
if (b[index] > 0)
{
a[index] = time + 0.1;
}
// calculating arrival,burst,final times
if (b[index] == 0)
{
c--;
p[index].FT = time;
p[index].WT = p[index].FT - p[index].AT - p[index].BT;
tot_wt += p[index].WT;
p[index].TAT = p[index].BT + p[index].WT;
tot_tat += p[index].TAT;
}
6.RESULT:-
The Round Robin algorithm is suitable for time-sharing systems where all processes are
considered equally important and should be given a fair share of CPU time. However, the
efficiency of the algorithm is not optimal for processes with very different burst times.
EXPRIMENT-7
1.OBJECTIVE:-
The aim of this experiment is to implement the Priority Scheduling algorithm in C, where
processes are executed based on their priority. The goal is to calculate and display the waiting
time, turnaround time, and completion time for each process based on their assigned priority.
2.REQUIREMENTS:-
Programming Language: C
Input:
• Number of processes.
• Arrival time, burst time (execution time), and priority of each process.
Output:
• Process ID, Arrival Time, Burst Time, Priority, Completion Time, Waiting Time, and
Turnaround Time for each process.
Tools: C compiler (e.g., GCC).
The Priority Scheduling algorithm is used to schedule processes in a manner where each process
is assigned a priority value. The key idea is that the process with the highest priority (usually
represented by the lowest numerical value) is executed first.
• Non-preemptive: Once a process starts executing, it runs to completion without being
interrupted.
• Preemptive version: In the preemptive version (also known as Preemptive Priority
Scheduling), a process with a higher priority can preempt a running process with a lower
priority.
Key Metrics:
• Waiting Time (WT): The total time a process spends in the ready queue before getting
CPU time.
WT=Turnaround Time−Burst Time
• Turnaround Time (TAT): The total time a process takes from its arrival to its completion.
TAT=Completion Time−Arrival Time
• Completion Time (CT): The time at which the process finishes execution.
5.OUTPUT:-
6.RESULT:-
1.The Priority Scheduling Algorithm ensures that processes with the highest priority (lowest
priority number) are executed first, which may lead to starvation for low-priority processes.
2.The Average Waiting Time and Average Turnaround Time are calculated to evaluate the
performance,
EXPERIMENT-8
1.OBJECTIVE:-
The objective of this program is to implement the Banker's Algorithm for Deadlock Avoidance in
an operating system. The Banker's Algorithm is used to determine whether the system is in a safe
state or not by analyzing the allocation of resources and processes. The program will simulate
resource allocation and determine if a deadlock will occur or if the system is in a safe state.
2.REQUIREMENT:-
Hardware Requirements:
• Computer or Workstation: Any machine with a functioning operating system.
• Memory: Sufficient memory to run the program and store data for multiple processes and
resources.
Software Requirements:
• C Compiler: GCC, Clang, or any C IDE (e.g., Visual Studio).
• Operating System: Any modern OS (Windows, Linux, macOS).
• Libraries: Standard C library (stdio.h, stdlib.h).
3.BANKER’S ALGORITHM:-
5.INPUT:-
6.OUTPUT:-
EXPRIMENT-9
1.OBJECTIVE:-
The objective of this program is to simulate and demonstrate the concepts of external and internal
fragmentation in memory management. The program will simulate memory allocation and
deallocation, illustrating how fragmentation occurs when memory is allocated in an inefficient
way. The program will also show how memory is wasted both inside allocated blocks (internal
fragmentation) and outside allocated blocks (external fragmentation).
2.REQUIREMENTS:-
Hardware Requirements:
Software Requirements:
3.FRAGMENTATION:-
External Fragmentation:
External fragmentation occurs when free memory is scattered in small blocks between allocated
blocks. Although there may be enough total free memory to satisfy a request, it cannot be
allocated as a contiguous block because of gaps between allocated blocks. This makes it impossible
to allocate larger memory blocks, even if the total free memory is sufficient.
Internal Fragmentation:
Internal fragmentation happens when memory is allocated in fixed-size blocks. If a block is larger
than what is actually needed, the remaining unused space inside the block is wasted. This unused
space is called internal fragmentation, and it typically happens when memory is allocated in units
of a fixed size, and the process doesn't use all the memory within the block.
5.OUTPUT:-