Operating System Assignment (1) New-1
Operating System Assignment (1) New-1
PRACTILE FILE
OF
SESSION: JAN-MAY(2023)
BACHELOR OF TECHNOLOGY
IN
DEPARTMENT OF ELECTRONICS & COMMUNICATION
ENGINEERING
1
INDEX
S.no Date Name of Experiment Page no Remark
1 11/01/2023 OS Practical 1 1-2
2 11/01/2023 OS Practical 2 3-7
3 18/01/2023 OS Practical 3 8-16
4 25/01/2023 OS Practical 4 17
5 01/02/2023 OS Practical 5 18-20
6 22/02/2023 OS Practical 6 21
7 22/02/2023 OS Practical 7 22-23
8 01/03/2023 OS Practical 8 24-25
9 01/03/2023 OS Practical 9 26-27
10 15/03/2023 OS Practical 10 28-33
11 22/03/2023 OS Practical 11 34-42
12 29/03/2023 OS Practical 12 43-48
13 12/04/2023 OS Practical 13 49-50
14 19/04/2023 OS Practical 14 51-56
PRACTICAL :1
2
AIM 1: To understand the basics of Operating Systems.
MS-Windows
Linux
Android
Mac OS
MS-DOS
TYPES OF OPERATING SYSTEM
3
allowed shared access of files, printers, security, applications, and other networking functions
over a small private network.
Real-Time operating systems
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.
PRACTICAL :2
4
AIM 2: To understand the UNIX/LINUX Operating Systems
Environments.
1. introduction to Unix/Linux
Unix is a computer Operating System which is capable of handling activities from multiple
users at the same time.
The main focus that was brought by the developers in this operating system was the kernel.
Unix was considered to be the heart of the operating system.
Linux is a community of open-source Unix like operating systems that are based on the Linux
kernel.
Initially, Linux was created for personal computers and gradually it was used in other
machines like servers, mainframe computers, supercomputers, etc. Nowadays, Linux is also
used in embedded systems like routers, automation controls, televisions, digital video
recorders, video game consoles, smartwatches, etc.
2.Architecture of Linux
Linux architecture has the following components:
1. Kernel: Kernel is the core of the Linux based operating system. It virtualizes the
common hardware resources of the computer to provide each process with its virtual
resources. This makes the process seem as if it is the sole process running on the
machine. The kernel is also responsible for preventing and mitigating conflicts
between different processes. Different types of the kernel are:
Monolithic kernel
Hybrid kernels
Exo kernels
Micro kernels
2. System library: Is the special types of the functions that are used to implement the
functionality of the operating system.
3. Shell: It is an interface to the kernel which hides the complexity of the kernel’s
functions from the users. It takes commands from the user and executes the kernel’s
functions.
4. Hardware layer: This layer consists all peripheral devices like RAM/HDD/CPU etc.
5. System utility: It provides the functionalities of an operating system to the user.
5
3. System call execution
A system call is a method for a computer program to request a service from the kernel of the
operating system on which it is running. A system call is a method of interacting with the
operating system via programs. A system call is a request from the computer software to an
operating system’s kernel.
The APPLICATION PROGRAM INTERFACE(API) connects the operating system’s
functions to user programs. It acts as a link between the operating system and a process,
allowing user-level programs to request operating system services. The kernel system can
only be accessed using system calls. System calls required for any programs that use
resources.
There are various situations where you must require system calls in the operating system.
Following of the situations are as follows:
6
4.Command structures
All the Linux/Unix commands are run in the terminal provided by the Linux system. This
terminal is just like the command prompt of windows OS. Linux/Unix commands are case-
sensitive. The terminal can be used to accomplish all the administrative tasks. This includes
package installation, file manipulation, and user management. Linux terminal is user-
interactive. The terminal outputs the result of commands which are specified by the user
itself. Execution of typed command is done only after you press the enter key.
7
PRACTICAL :3
AIM 3: To understand the concept of shell and related commands
1.concept oof shell
A shell is a special user program which provide an interface to user to use operating system
services. Shell accepts human readable commands from user and convert them something
which kernel can understand. It is a command language interpreter that execute commands
read from input devices such as keyboards or from files. The shell gets started when the user
logs in or start the terminal.
2. types of shell
1. Sh
2. Ksh
3. Csh
4. Restricted shell
5. Bourne again shell (BASH)
3.Ls command and its options
The ls is the list command in Linux. It will show the full list or content of your directory. Just
type ls and press the enter key. The whole content will be shown. ls is a command used to list
computer directories and files in Unix-like and Unix operating systems. It is developed by the
Single Unix Specification and POSIX.
ls option Description
8
according to their size, then you can use
(ls -lhS) command.
9
5.Introduction and options for Cat command
This command displays the contents of one or more files without having to open the file for
editing. The cat command has the option of displaying the file content along with the tab
space within the text.
1. Feeding output of one command to another by pipeline.
Pipe is used to combine two or more commands, and in this, the output of one command acts
as input to another command, and this command’s output may act as input to the next
command and so on. It can also be visualized as a temporary connection between two or
more commands/ programs/ processes. The command line programs that do the further
processing are referred to as filters. This direct connection between commands/ programs/
processes allows them to operate simultaneously and permits data to be transferred between
them continuously rather than having
to pass it through temporary text files or through the display screen.
Pipes are unidirectional I.e. data flows from left to right through the pipeline.
7. Ways for signing off from Linux.
a) pkill command – Kill processes by name.
b) kill command – terminate or signal a process.
c) logout command – Logout of a login shell. This command can be used by normal users to
end their own session.
8. Locating commands
locate command in Linux is used to find the files by name. There is two most widely used
file searching utilities accessible to users are called find and locate. The locate utility works
better and faster than find command counterpart because instead of searching the file system
when a file search is initiated, it would look through a database. This database contains bits
and parts of files and their corresponding paths on your system. By default, locate command
does not check whether the files found in the database still exist and it never reports files
created after the most recent update of the relevant database.
9. PATH and SHELL variable
A subset of environment variables, such as PATH, affects the behaviour of the shell itself.
Shell (local) variables – Variables that affect only the current shell. In the C shell, a set of
these shell variables have a special relationship to a corresponding set of environment
variables. These shell variables are user, term, home, and path.
10. Combining the commands.
There are several simple ways you can combine several commands on a single command
line:
10
12. Cal and Date command with its different options.
The Cal command is a calendar command in Linux which is used to see the calendar of a
specific month or a whole year. The rectangular bracket means it is optional, so if used
without an option, it will display a calendar of the current month and year.
the date command displays the current date and time, including the abbreviated day name,
abbreviated month name, day of the month, the time separated by colons, the time zone
name, and the year.
13. man and help command
man command in Linux is used to display the user manual of any command that we can
run on the terminal. It provides a detailed view of the command which includes NAME,
SYNOPSIS, DESCRIPTION, OPTIONS, EXIT STATUS, RETURN VALUES, ERRORS,
FILES, VERSIONS, EXAMPLES, AUTHORS.
The help command is a shell built-in internal command. It accepts a text string as the
command line argument and searches the supplied string in the shell's documents.
11
PRACTICAL :4
AIM 4: To understand internal and external commands in Linux.
Internal Commands: Commands which are built into the shell. For all the shell
built-in commands, execution of the same is fast in the sense that the shell doesn’t
have to search the given path for them in the PATH variable, and also no process
needs to be spawned for executing it.
Examples: source, cd, fg, etc.
External Commands: Commands which aren’t built into the shell. When an
external command has to be executed, the shell looks for its path given in the
PATH variable, and also a new process has to be spawned and the command gets
executed. They are usually located in /bin or /usr/bin. For example, when you
execute the “cat” command, which usually is at /usr/bin, the executable
/usr/bin/cat gets executed.
Examples: ls, cat etc.
PRACTICAL:5
AIM 5: To understand the basic file attributes.
1.Name
Every file carries a name by which the file is recognized in the file system. One directory
cannot have two files with the same name.
2.Identifier
Along with the name, Each File has its own extension which identifies the type of the file.
For example, a text file has the extension .txt, A video file can have the extension .mp4.
3.Type
In a File System, the Files are classified in different types such as video files, audio files, text
files, executable files, etc.
4.Location
In the File System, there are several locations on which, the files can be stored. Each file
carries its location as its attribute.
5.Size
The Size of the File is one of its most important attribute. By size of the file, we mean the
12
number of bytes acquired by the file in the memory.
6.Protection
The Admin of the computer may want the different protections for the different files.
Therefore each file carries its own set of permissions to the different group of Users.
Every file carries a time stamp which contains the time and date on which the file is last
modified.
PRACTICAL :6
o Command Mode: In command mode, actions are taken on the file. The vi editor
starts in command mode. Here, the typed words will act as commands in vi editor. To
pass a command, you need to be in command mode.
o Insert Mode: In insert mode, entered text will be inserted into the file. The Esc key
will take you to the command mode from insert mode.
By default, the vi editor starts in command mode. To enter text, you have to be in insert
mode, just type 'i' and you'll be in insert mode. Although, after typing i nothing will appear
on the screen but you'll be in insert mode. Now you can type anything.
To exit from insert mode press Esc key, you'll be directed to command mode.
If you are not sure which mode you are in, press Esc key twice and you'll be in command
mode.
PRACTICAL:7
13
assign, and delete variables.
Variable Names--
The name of a variable can contain only letters (a to z or A to Z), numbers ( 0 to 9) or the
underscore character ( _).
By convention, Unix shell variables will have their names in UPPERCASE.
The following examples are valid variable names −
_ALI
TOKEN_A
VAR_1
VAR_2
Following are the examples of invalid variable names −
2_VAR
-VARIABLE
VAR1-VAR2
VAR_A!
The reason you cannot use other characters such as !, *, or - is that these characters have a
special meaning for the shell.
Command-Line Arguments-
The command-line arguments $1, $2, $3, ...$9 are positional parameters, with $0 pointing to
the actual command, program, shell script, or function and $1, $2, $3, ...$9 as the arguments
to the command.
Following script uses various special variables related to the command line −
#!/bin/sh
PRACTICAL :8
14
logical and append.
While Loops-
It is possible to use a while loop as part of the body of another while loop.
Syntax
while command1 ; # this is loop1, the outer loop
do
Statement(s) to be executed if command1 is true
a=0
while [ "$a" -lt 10 ] # this is loop1
do
b="$a"
while [ "$b" -ge 0 ] # this is loop2
do
echo -n "$b "
b=`expr $b - 1`
done
echo
a=`expr $a + 1`
done
This will produce the following result. It is important to note how echo -n works here. Here -
n option lets echo avoid printing a new line character.
0
10
210
3210
43210
543210
6543210
76543210
876543210
9876543210
15
PRACTICAL :9
AIM 9: To understand shell scripting using file text operators and other
basic operators.
There are various operators supported by each shell. We will discuss in detail about
Bourne shell (default shell) in this chapter.
We will now discuss the following operators −
Arithmetic Operators
Relational Operators
Boolean Operators
String Operators
File Test Operators
Bourne shell didn't originally have any mechanism to perform simple arithmetic operations
but it uses external programs, either awk or expr.
The following example shows how to add two numbers −
#!/bin/sh
val=`expr 2 + 2`
echo "Total value : $val"
The above script will generate the following result −
Total value : 4
The following points need to be considered while adding −
There must be spaces between operators and expressions. For example, 2+2 is
not correct; it should be written as 2 + 2.
The complete expression should be enclosed between ‘ ‘, called the backtick.
Arithmetic Operators
The following arithmetic operators are supported by Bourne Shell.
Assume variable a holds 10 and variable b holds 20 then −
+ (Addition) Adds values on either side of the operator `expr $a + $b` will
give 30
- (Subtraction) Subtracts right hand operand from left hand operand `expr $a - $b` will
give -10
* (Multiplication) Multiplies values on either side of the operator `expr $a \* $b` will
give 200
16
/ (Division) Divides left hand operand by right hand operand `expr $b / $a` will
give 2
% (Modulus) Divides left hand operand by right hand operand and `expr $b % $a` will
returns remainder give 0
= (Assignment) a = $b would
Assigns right operand in left operand assign value of b
into a
== (Equality) Compares two numbers, if both are same then returns true. [ $a == $b ] would
return false.
!= (Not Equality) Compares two numbers, if both are different then returns [ $a != $b ] would
true. return true.
It is very important to understand that all the conditional expressions should be inside square
braces with spaces around them, for example [ $a == $b ] is correct whereas, [$a==$b] is
incorrect.
All the arithmetical calculations are done using long integers.
Relational Operators
Bourne Shell supports the following relational operators that are specific to numeric values.
These operators do not work for string values unless their value is numeric.
For example, following operators will work to check a relation between 10 and 20 as well as
in between "10" and "20" but not in between "ten" and "twenty".
Assume variable a holds 10 and variable b holds 20 then −
Show Examples
-eq Checks if the value of two operands are equal or not; if yes, then the [ $a -eq $b ] is
condition becomes true. not true.
-ne Checks if the value of two operands are equal or not; if values are not
[ $a -ne $b ] is true.
equal, then the condition becomes true.
-gt Checks if the value of left operand is greater than the value of right [ $a -gt $b ] is
operand; if yes, then the condition becomes true. not true.
-lt Checks if the value of left operand is less than the value of right
[ $a -lt $b ] is true.
operand; if yes, then the condition becomes true.
-ge Checks if the value of left operand is greater than or equal to the [ $a -ge $b ] is not
value of right operand; if yes, then the condition becomes true. true.
17
-le Checks if the value of left operand is less than or equal to the value
[ $a -le $b ] is true.
of right operand; if yes, then the condition becomes true.
It is very important to understand that all the conditional expressions should be placed inside
square braces with spaces around them. For example, [ $a <= $b ] is correct whereas, [$a <=
$b] is incorrect.
Boolean Operators
The following Boolean operators are supported by the Bourne Shell.
Assume variable a holds 10 and variable b holds 20 then −
Show Examples
! This is logical negation. This inverts a true condition into false and
[ ! false ] is true.
vice versa.
-o This is logical OR. If one of the operands is true, then the condition [ $a -lt 20 -o $b -gt
becomes true.
100 ] is true.
-a This is logical AND. If both the operands are true, then the condition [ $a -lt20 -a $b -gt
becomes true otherwise false.
100 ] is false.
-b file Checks if file is a block special file; if yes, then the condition [ -b $file ] is false.
becomes true.
-c file Checks if file is a character special file; if yes, then the condition [ -c $file ] is false.
becomes true.
-d file Checks if file is a directory; if yes, then the condition becomes [ -d $file ] is not true.
true.
18
special file; if yes, then the condition becomes true.
-g file Checks if file has its set group ID (SGID) bit set; if yes, then the [ -g $file ] is false.
condition becomes true.
-k file Checks if file has its sticky bit set; if yes, then the condition [ -k $file ] is false.
becomes true.
-p file Checks if file is a named pipe; if yes, then the condition becomes [ -p $file ] is false.
true.
-t file Checks if file descriptor is open and associated with a terminal; [ -t $file ] is false.
if yes, then the condition becomes true.
-r file Checks if file is readable; if yes, then the condition becomes [ -r $file ] is true.
true.
-w file Checks if file is writable; if yes, then the condition becomes true. [ -w $file ] is true.
-x file Checks if file is executable; if yes, then the condition becomes [ -x $file ] is true.
true.
-s file Checks if file has size greater than 0; if yes, then condition [ -s $file ] is true.
becomes true.
-e file Checks if file exists; is true even if file is a directory but exists. [ -e $file ] is true.
PRACTICAL :10
A. FCFS
#include<iostream>
using namespace std;
wt[0] = 0;
19
for (int i = 1; i < n ; i++ )
wt[i] = bt[i-1] + wt[i-1] ;
}
int main()
{
20
int n = sizeof processes / sizeof processes[0];
findavgTime(processes, n, burst_time);
return 0;
}
B. SJF (NONPREEMPTIVE)
#include <iostream>
using namespace std;
int main() {
int A[100][4];
int i, j, n, total = 0, index, temp;
float avg_wt, avg_tat;
21
for (i = 0; i < n; i++) {
cout << "P" << i + 1 << ": ";
cin >> A[i][1];
A[i][0] = i + 1;
}
temp = A[i][0];
A[i][0] = A[index][0];
A[index][0] = temp;
}
A[0][2] = 0;
for (i = 1; i < n; i++) {
A[i][2] = 0;
for (j = 0; j < i; j++)
A[i][2] += A[j][1];
total += A[i][2];
}
avg_wt = (float)total / n;
total = 0;
cout << "P BT WT TAT" << endl;
avg_tat = (float)total / n;
cout << "Average Waiting Time= " << avg_wt << endl;
cout << "Average Turnaround Time= " << avg_tat << endl;
}
22
C. SJF (PREEMPTIVE)
#include <iostream>
#include <climits>
using namespace std;
struct Process {
int pid;
int bt;
int at;
};
23
int shortest = 0, finish_time;
bool check = false;
while (complete != n) {
if (check == false) {
t++;
continue;
}
rt[shortest]--;
minm = rt[shortest];
if (minm == 0)
minm = INT_MAX;
if (rt[shortest] == 0) {
complete++;
check = false;
finish_time = t + 1;
wt[shortest] = finish_time -
proc[shortest].bt -
proc[shortest].at;
if (wt[shortest] < 0)
wt[shortest] = 0;
}
t++;
}
}
24
void findTurnAroundTime(Process proc[], int n,
int wt[], int tat[])
{
findWaitingTime(proc, n, wt);
int main()
{
Process proc[] = { { 1, 6, 2 }, { 2, 2, 5 },
{ 3, 8, 1 }, { 4, 3, 0}, {5, 4, 4} };
int n = sizeof(proc) / sizeof(proc[0]);
findavgTime(proc, n);
25
return 0;
}
PRACTICAL:11
A. ROUND ROBIN
#include<iostream>
using namespace std;
int rem_bt[n];
for (int i = 0 ; i < n ; i++)
rem_bt[i] = bt[i];
int t = 0;
26
while (1)
{
bool done = true;
if (rem_bt[i] > 0)
{
done = false;
if (rem_bt[i] > quantum)
{
t += quantum;
rem_bt[i] -= quantum;
}
else
{
t = t + rem_bt[i];
wt[i] = t - bt[i];
rem_bt[i] = 0;
}
}
}
if (done == true)
break;
}
}
27
findWaitingTime(processes, n, bt, wt, quantum);
int main()
{
int quantum = 2;
findavgTime(processes, n, burst_time, quantum);
return 0;
}
28
B. PRIORITY
#include<iostream>
#include<limits>
using namespace std;
class Process{
public:
string processName;
int arrivalTime;
int burstTime;
int priority;
int remainingTime;
int responseTime;
int completionTime;
int waitingTime;
int turnAroundTime;
void initialize(){
remainingTime = burstTime;
29
}
};
int main(){
int numOfProcesses;
cout << "Enter no. of processes: ";
cin >> numOfProcesses;
Process processes[numOfProcesses];
for(int n=0;n<numOfProcesses;n++){
cout << "\nEnter Process Name for " << (n+1) << ": ";
cin >> processes[n].processName;
cout << "Enter Arrival Time for Process " << (n+1) << ": ";
cin >> processes[n].arrivalTime;
cout << "Enter Burst Time for Process " << (n+1) << ": ";
cin >> processes[n].burstTime;
cout << "Enter Priority for Process " << (n+1) << ": ";
cin >> processes[n].priority;
processes[n].initialize();
}
for(int i=0;i<numOfProcesses-1;i++){
for(int j=i+1;j<numOfProcesses;j++){
if(processes[j].arrivalTime < processes[i].arrivalTime){
Process temp = processes[j];
processes[j] = processes[i];
processes[i] = temp;
}
}
}
int currentTime = 0;
while(true){
for(int i=0;i<numOfProcesses;i++){
if(processes[i].remainingTime > 0){
isAllCompleted = false;
if(processes[i].arrivalTime <= currentTime){
if(processes[i].priority < currentHighestPriority){
currentHighestPriority = processes[i].priority;
30
currentHighestPriorityIndex = i;
}
}
}
}
if(isAllCompleted){
break;
}
if(processes[currentHighestPriorityIndex].remainingTime ==
processes[currentHighestPriorityIndex].burstTime){
processes[currentHighestPriorityIndex].responseTime =
currentTime;
}
processes[currentHighestPriorityIndex].remainingTime--;
currentTime++;
if(processes[currentHighestPriorityIndex].remainingTime == 0){
processes[currentHighestPriorityIndex].completionTime =
currentTime;
}
}
int sumResponseTime = 0;
int sumCompletionTime = 0;
int sumWaitingTime = 0;
int sumTurnAroundTime = 0;
for(int n=0;n<numOfProcesses;n++){
cout << "\nProcess " << processes[n].processName << ":\n";
cout << "Response Time: " << processes[n].responseTime << endl;
cout << "Completion Time: " << processes[n].completionTime << endl;
processes[n].turnAroundTime = processes[n].completionTime -
processes[n].arrivalTime;
processes[n].waitingTime = processes[n].turnAroundTime -
processes[n].burstTime;
cout << "Waiting Time: " << processes[n].waitingTime << endl;
cout << "Turn Around Time: " << processes[n].turnAroundTime << "\n" <<
endl;
sumResponseTime += processes[n].responseTime;
sumCompletionTime += processes[n].completionTime;
sumWaitingTime += processes[n].waitingTime;
sumTurnAroundTime += processes[n].turnAroundTime;
}
31
cout << "\n\nAverage Response Time for " << (numOfProcesses) << "
Processes: " << (float) sumResponseTime/numOfProcesses;
cout << "\n\nAverage Completion Time for " << (numOfProcesses) << "
Processes: " << (float) sumCompletionTime/numOfProcesses;
cout << "\n\nAverage Waiting Time for " << (numOfProcesses) << " Processes: "
<< (float) sumWaitingTime/numOfProcesses;
cout << "\n\nAverage Turn Around Time for " << (numOfProcesses) << "
Processes: " << (float) sumTurnAroundTime/numOfProcesses;
return 0;
}
C. PRIORITY
#include <iostream>
#define totalprocess 5
32
struct process
{
int at,bt,pr,pno;
};
process proc[50];
for(int i=1;i<totalprocess;i++)
{
service[i]=proc[i-1].bt+service[i-1];
wt[i]=service[i]-proc[i].at;
if(wt[i]<0)
{
wt[i]=0;
}
}
33
for(int i=0;i<totalprocess;i++)
{
tat[i]=proc[i].bt+wt[i];
}
void findgc()
{
int wt[50],tat[50];
double wavg=0,tavg=0;
get_wt_time(wt);
get_tat_time(tat,wt);
int stime[50],ctime[50];
stime[0] = proc[0].at;
ctime[0]=stime[0]+tat[0];
for(int i=1;i<totalprocess;i++)
{
stime[i]=ctime[i-1];
ctime[i]=stime[i]+tat[i]-wt[i];
}
cout<<"Process_no\tStart_time\tComplete_time\tTurn_Around_Time\tWaiting_Time"<<endl
;
for(int i=0;i<totalprocess;i++)
{
wavg += wt[i];
tavg += tat[i];
cout<<proc[i].pno<<"\t\t"<<
stime[i]<<"\t\t"<<ctime[i]<<"\t\t"<<
tat[i]<<"\t\t\t"<<wt[i]<<endl;
}
34
}
int main()
{
int arrivaltime[] = { 1, 2, 3, 4, 5 };
int bursttime[] = { 3, 5, 1, 7, 4 };
int priority[] = { 3, 4, 1, 7, 8 };
for(int i=0;i<totalprocess;i++)
{
proc[i].at=arrivaltime[i];
proc[i].bt=bursttime[i];
proc[i].pr=priority[i];
proc[i].pno=i+1;
}
sort(proc,proc+totalprocess,comp);
findgc();
return 0;
}
35
PRACTICAL:12
1. PRODUCER CONSUMER
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#define NUM_THREADS 2
#define BUFFER_SIZE 10
typedef struct {
int buf[BUFFER_SIZE];
int w_index;
int r_index;
int filled_slots;
}CIR_BUF;
pthread_mutex_t sync_mutex;
sem_t sem_empty_slots;
sem_t sem_filled_slots;
void *consumer(void *arg) {
while(1) {
sem_wait(&sem_filled_slots);
pthread_mutex_lock(&sync_mutex);
36
pthread_mutex_lock(&sync_mutex);
CirBuf.buf[CirBuf.w_index] = CirBuf.w_index;
cout << "produced " << CirBuf.buf[CirBuf.w_index] << std::endl <<
std::flush;
CirBuf.w_index = (CirBuf.w_index + 1)%BUFFER_SIZE;
CirBuf.filled_slots++;
pthread_mutex_unlock(&sync_mutex);
sem_post(&sem_filled_slots);
}
return NULL;
}
int main()
{
pthread_t thread_id[NUM_THREADS];
//int thread_arg[NUM_THREADS];
if(pthread_mutex_init(&sync_mutex, NULL)) {
cout << "Mutex not init" << endl;
}
if(sem_init(&sem_empty_slots, 0, BUFFER_SIZE)) {
cout << "Init Sem empty slots failed" << endl;
}
if(sem_init(&sem_filled_slots, 0, 0)) {
cout << "Init Sem filled slots failed" << endl;
}
pthread_join(thread_id[0], NULL);
pthread_join(thread_id[1], NULL);
pthread_mutex_destroy(&sync_mutex);
sem_destroy(&sem_empty_slots);
sem_destroy(&sem_filled_slots);
return 0;
}
37
2. READER WRITER
#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;
class monitor {
private:
int rcnt;
int wcnt;
int waitr;
int waitw;
38
pthread_cond_t canread;
pthread_cond_t canwrite;
pthread_mutex_t condlock;
public:
monitor()
{
rcnt = 0;
wcnt = 0;
waitr = 0;
waitw = 0;
pthread_cond_init(&canread, NULL);
pthread_cond_init(&canwrite, NULL);
pthread_mutex_init(&condlock, NULL);
}
void beginread(int i)
{
pthread_mutex_lock(&condlock);
// reader suspended
pthread_cond_wait(&canread, &condlock);
waitr--;
}
void endread(int i)
{
pthread_mutex_lock(&condlock);
if (--rcnt == 0)
39
pthread_cond_signal(&canwrite);
pthread_mutex_unlock(&condlock);
}
void beginwrite(int i)
{
pthread_mutex_lock(&condlock);
void endwrite(int i)
{
pthread_mutex_lock(&condlock);
wcnt = 0;
if (waitr > 0)
pthread_cond_signal(&canread);
else
pthread_cond_signal(&canwrite);
pthread_mutex_unlock(&condlock);
}
M;
40
{
int c = 0;
int i = (int)id;
while (c < 5) {
usleep(1);
M.beginwrite(i);
M.endwrite(i);
c++;
}
}
int main()
{
pthread_t r[5], w[5];
int id[5];
for (int i = 0; i < 5; i++) {
id[i] = i;
pthread_create(&r[i], NULL, &reader, &id[i]);
41
42
PRACTICAL:13
A. SAFE
#include <stdio.h>
int main()
{
int n, m, i, j, k;
n = 5;
m = 4;
int alloc[5][3] = { { 0, 1, 0},
{ 2, 0, 0},
{ 3, 0, 2 },
{ 2, 1, 1},
{ 0, 0, 2} };
int max[5][3] = { { 7, 5, 3 },
{ 3, 2, 2 },
{ 9, 0, 2 },
{ 2, 2, 2 },
{ 4, 3, 3} };
int flag = 0;
for (j = 0; j < m; j++) {
if (need[i][j] > avail[j]){
flag = 1;
break;
}
}
43
if (flag == 0) {
ans[ind++] = i;
for (y = 0; y < m; y++)
avail[y] += alloc[i][y];
f[i] = 1;
}
}
}
}
int flag = 1;
for(int i=0;i<n;i++)
{
if(f[i]==0)
{
flag=0;
printf("The following system is not safe");
break;
}
}
if(flag==1)
{
printf("Following is the SAFE Sequence\n");
for (i = 0; i < n - 1; i++)
printf(" P%d ->", ans[i]);
printf(" P%d", ans[n - 1]);
}
return 0;
}
B. UNSAFE
#include <stdio.h>
int main()
{
int n, m, i, j, k;
n = 5;
m = 4;
int alloc[5][4] = { { 0, 1, 0,1 },
{ 2, 0, 0,0 },
{ 3, 0, 2,1 },
{ 2, 1, 1,0 },
{ 0, 0, 2,0 } };
int max[5][4] = { { 7, 5, 3, 1 },
{ 3, 2, 2, 3 },
{ 9, 0, 2, 2 },
44
{ 2, 2, 2, 1 },
{ 4, 3, 3, 3 } };
int avail[4] = { 3, 3, 2, 1 };
int flag = 0;
for (j = 0; j < m; j++) {
if (need[i][j] > avail[j]){
flag = 1;
break;
}
}
if (flag == 0) {
ans[ind++] = i;
for (y = 0; y < m; y++)
avail[y] += alloc[i][y];
f[i] = 1;
}
}
}
}
int flag = 1;
for(int i=0;i<n;i++)
{
if(f[i]==0)
{
flag=0;
printf("The following system is not safe");
break;
}
}
if(flag==1)
45
{
printf("Following is the SAFE Sequence\n");
for (i = 0; i < n - 1; i++)
printf(" P%d ->", ans[i]);
printf(" P%d", ans[n - 1]);
}
return 0;
}
PRACTICAL 14
a) FIRST FIT
#include<bits/stdc++.h>
using namespace std;
46
int processSize[], int n)
{
int allocation[n];
allocation[i] = j;
blockSize[j] -= processSize[i];
break;
}
}
}
}
}
int main()
{
int blockSize[] = {500, 400, 200, 300, 600};
int processSize[] = {212, 417, 312, 426};
int m = sizeof(blockSize) / sizeof(blockSize[0]);
int n = sizeof(processSize) / sizeof(processSize[0]);
47
firstFit(blockSize, m, processSize, n);
return 0 ;
}
b) BEST FIT
#include<iostream>
using namespace std;
int allocation[n];
48
if (blockSize[j] >= processSize[i])
{
if (best == -1)
best = j;
else if (blockSize[best] > blockSize[j])
best = j;
}
}
if (best != -1)
{
allocation[i] = best;
blockSize[best] -= processSize[i];
}
}
int main()
{
int blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 417, 112, 426,500};
int m = sizeof(blockSize) / sizeof(blockSize[0]);
int n = sizeof(processSize) / sizeof(processSize[0]);
return 0 ;
}
49
c) WORST FIT
#include<bits/stdc++.h>
using namespace std;
int allocation[n];
if (worst != -1)
50
{
allocation[i] = worst;
blockSize[worst] -= processSize[i];
}
}
int main()
{
int blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 517, 212, 426,112};
int m = sizeof(blockSize)/sizeof(blockSize[0]);
int n = sizeof(processSize)/sizeof(processSize[0]);
return 0 ;
51
}
52