191CS42B - Os-Record
191CS42B - Os-Record
191CS42B - Os-Record
ISO9001:2015 CertifiedInstitution,AccreditedbyNBA(BME,CSE,ECE,EEE,IT&MECH),AccreditedbyNAAC
NAME :
REGISTER NO :
VM NO : VM -
BRANCH : CSE
YEAR : II
SEMESTER : IV
Vision
To emerge as centre for academic excellence in the field of Computer Science and Engineering
by exposure to research and industry practices.
Mission
To provide good teaching and learning environment with conducive research atmosphere in the
field of Computer Science and Engineering.
To propagate lifelong learning.
To impart the right proportion of knowledge, attitudes and ethics in students to enable them take
up positions of responsibility in the society and make significant contributions.
1
An Autonomous Institution
Approved by AICTE, Affiliated to Anna University, Chennai.
ISO 9001:2015 Certified Institution, Accredited by NBA (BME, CSE, ECE, EEE, IT & MECH),
Accredited by NAAC.
#42, Avadi-Vel Tech Road, Avadi, Chennai- 600062, Tamil Nadu, India.
CERTIFICATE
Submitted for the University Practical Examination held on ………………... at VEL TECH
MULTI TECH Dr.RANGARAJANDr.SAKUNTHALA ENGINEERING COLLEGE,
No.42, AVADI – VEL TECH ROAD, AVADI, CHENNAI-600062.
Signature of Examiners
InternalExaminer ExternalExaminer
2
Department of Computer Science and Engineering
Ability to identify, formulate and analyze complex Computer Science and Engineering
problems in the areas of hardware, software, theoretical Computer Science and
PEO1
applications to reach significant conclusions by applying Mathematics, Natural sciences,
Computer Science and Engineering principles.
Design solutions for complex computer science and engineering problems using state of
the art tools and techniques, components or processes that meet specified needs with
PEO3
appropriate consideration for public health and safety, cultural, societal, and
environmental considerations.
The design techniques, analysis and the building, testing, operation and maintenance
PSO2
of networks, databases, security and computer systems (both hardware and software).
An ability to identify, formulate and solve hardware and software problems using
PSO3
sound computer engineering principles.
3
Department of Computer Science and Engineering
PROGRAMME OUTCOMES (POs)
Ability to identify, formulate and analyze complex Computer Science and Engineering problems in the
PO2 areas of hardware, software, theoretical Computer Science and applications to reach significant
conclusions by applying Mathematics, Natural sciences, Computer Science and Engineering principles.
Design solutions for complex computer science and engineering problems and design systems,
PO3 components or processes that meet specified needs with appropriate consideration for public health and
safety, cultural, societal, and environmental considerations.
Ability to use research based knowledge and research methods to perform literature survey, design
experiments for complex problems in designing, developing and maintaining a computing system,
PO4
collect data from the experimental outcome, analyze and interpret valid/interesting patterns and
conclusions from the data points.
Ability to create, select and apply state of the art tools and techniques in designing, developing and
PO5
testing a computing system or its component.
Apply reasoning informed by contextual knowledge to assess societal, health, safety, legal and cultural
issues and the consequent responsibilities relevant to professional engineering practice in system
PO6
development and solutions to complex engineering problems related to system fundamentals, software
development, networking & communication, and information assurance & security.
Understand and evaluate the sustainability and impact of professional engineering work in the solution
PO7 of complex engineering problems related to system fundamentals, software development, networking &
communication, and information assurance & security in societal and environmental contexts.
Apply ethical principles and commit to professional ethics and responsibilities and norms of computer
PO8
science and engineering practice.
Ability to function as an individual and as a team player or leader in multidisciplinary teams and strive
PO9
towards achieving a common goal.
Communicate effectively on complex engineering activities with the engineering community and with
PO10 society at large, such as being able to comprehend and write effective reports and design documentation,
make effective presentations, and give and receive clear instructions.
Demonstrate knowledge and understanding of engineering management principles and economic
PO11 decision making and apply these to one’s own work, as a member and leader in a team, to manage
projects and in multidisciplinary environments.
Recognize the need for, and have the preparation and ability to engage in independent and lifelong
PO12
learning in the broadest context of technological change.
4
COURSE OBJECTIVES
COURSE OUTCOMES
At the end of the course, the student should be able to
Course CO Statements
Outcome
CO1 Write functions to implement linear and non-linear data structure operations.
CO2 Suggest appropriate linear / non-linear data structure operations for solving a given problem
CO3 Appropriately use the linear / non-linear data operations for a given problem
Apply appropriate hash functions that result in a collision free scenario for data storage and
CO4
retrieval
CO5 Apply appropriate sorting and searching functions based on the application.
5
INDEX
FACULTYS
S.NO DATE LIST OFEXPERIMENTS PAGE NO CO’s IGN
CO1
2e READDIR SYSTEM CALL
CO1
2f OPEN SYSTEM CALL
CO1
2g READ SYSTEM CALL
CO1
2h WRITE SYSTEM CALL
CO1
3a LS COMMAND
CO1
3b GREP COMMAND
CO1
3c CP COMMAND
CO1
3d RM COMMAND
CO1
4 SHELL PROGRAMMING
6
5d ROUND ROBIN SCHEDULING CO2
7b WHO | WC -l CO3
7
EX.No.:1 DATE:
BASIC UNIX COMMANDS
AIM
To study and execute Unix commands.
LOGIN
Type telnetserver_ipaddress in run window.
User has to authenticate himself by providing username and password. Once verified, a greeting and
$ prompt appears. The shell is now ready to receive commands from the user. Options suffixed with
a hyphen (–) and arguments are separated by space
GENERAL COMMANDS
Command Function
Cal year Displays calendar for all months of the specified year
Cal month year Displays calendar for the specified month of the year
Who Login details of all users such as their IP, Terminal No, User name
lp file Allows the user to spool a job along with others in a print queue.
Exit Exit from a process. If shell is the only process then logs out
8
DIRECTORY COMMANDS
Command Function
Mkdirdir A directory is created in the given name under the current directory
cd subdir Change Directory. If the subdir starts with / then path starts from root
(absolute) otherwise from current working directory
FILE COMMANDS
Command Function
cat > filename To create a file with some contents. To end typing press Ctrl+d. The >
symbol means redirecting output to a file. (< for input)
cp –isrc des Warns the user prior to overwriting the destination file
cp –r src des Copies the entire directory, all its sub-directories and files.
mv old new To rename an existing file or directory. –i option can also be used
rm file Used to delete a file or group of files. –i option can also be used
9
ls name To check whether a file or directory exists.
cmp file1 file2 Used to compare two files. Displays nothing if files are identical.
chmod perm file Changes permission for the specified file. (r=4, w=2, x=1) chmod 740 file
sets all rights for user, read only for groups and no rights for others
The commands can be combined using the pipeline (|) operator. For example, number of users
logged in can be obtained as.
who | wc -l
Finally to terminate the unix session execute the command exit or logout
OUTPUT
$ date
Sat Apr 9 13:03:47 IST 2011
$ date +%D
04/09/11
$ date +%T
13:05:33
$ date +%Y
2011
$ date +%H
13
$ cal 08 1998
August1998
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
10
$ who
root :0 Apr 9 08:41
vijai pts/0 Apr 9 13:00 (scl-64)
cse4001 pts/3 Apr 9 13:18 (scl-41:smkfomra.com)
$ uname
Linux
$ uname -r
2:4:20-8smp
$ uname -n
localhost.localdomain
$ echo $HOME
/home/vijai
$ echo $USER
vijai
$ bc
3+5
8
$ pwd
/home/vijai/shellscripts/loops
$ mkdir filter
$ ls
filter list.sh regexpr shellscripts
$ cd shellscripts/loops/
$
$ cd
$
$ cd /
[vijai@localhost /]
$ [vijai@localhost /]
$ cd /home/vijai/shellscripts/loops/
$ cd ..
[vijai@localhostshellscripts]
$
$ rmdir filter
$ ls
list.sh regexpr shellscripts
$ cat >greet
11
hi ai&ds
wishing u the best
$ cat greet
hi ece-a wishing u the best
$ cat >>greet
bye
$ cat greet
hi cse
wishing u the best
bye
$ ls
Greet list.sh regexpr shellscripts
$ ls -a
. .bash_logout .canna .gtkrcregexpr .viminfo.tmp .. .bash_profile .emacs
$ ls -l
-rw-rw-r-- 1 vijai vijai 32 Apr 11 14:52 greet
-rw-rw-r-- 1vijai vijai 30 Apr 4 13:58 list.sh
drwxrwxr-x 2 vijai vijai 4096 Apr 9 14:30 regexpr
$ cp greet ./regexpr/
$ ls
greet list.sh regexprshellscripts
$ ls ./regexpr
demo greet
$ cp -igreet ./regexpr/
cp: overwrite 'greet'? n
$ mv greet greet.txt
$ ls
greet.txt list.sh regexpr shellscripts
$ mv greet.txt ./regexpr/
$ ls
list.sh regexpr shellscripts
$ rm -i *.sh
rm: remove regular file 'fact.sh'? y
rm: remove regular file 'prime.sh'? y
$ ls
list.sh regexpr shellscripts
$ wc list.sh
12
4 9 30 list.sh
$ wc -l list.sh
4 list.sh
$ cmp list.sh fact.sh
list.sh fact.sh differ: byte 1, line 1
$ ls -l list.sh
-rw-rw-r-- 1 vijai vijai 30 Apr 4 13:58 list.sh
$ chmodug+x list.sh
$ ls -l list.sh
-rwxrwxr-- 1 vijai vijai 30 Apr 4 13:58 list.sh
$ chmod 740 list.sh
$ ls -l list.sh
-rwxr----- 1 vijai vijai 30 Apr 4 13:58 list.sh
RESULT:
Thus the study and execution of Unix commands has been completed successfully.
13
EX. No.:2a DATE:
PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
main()
{
14
pid_tpid;
int x = 5;
pid = fork();
x++;
if (pid< 0)
{
printf("Process creation error");
exit(-1);
}
else if (pid == 0)
{
printf("Child process:");
printf("\nProcess id is %d", getpid());
printf("\nValue of x is %d", x);
printf("\nProcess id of parent is %d\n", getppid());
}
else
{
printf("\nParent process:");
printf("\nProcess id is %d", getpid());
printf("\nValue of x is %d", x);
printf("\nProcess id of shell is %d\n", getppid());
}
}
OUTPUT
$ gccfork.c
$ ./a.out
Child process:
Process id is 19499
Value of x is 6
Process id of parent is 19498
Parent process: Process id is 19498
Value of x is 6 Process id of shell is 3266
RESULT
Thus a child process is created with copy of its parent's address space.
15
EX.No.:2b DATE:
WAIT SYSTEM CALL
AIM
To block a parent process until child completes using wait system call.
wait()
The wait system call causes the parent process to be blocked until a child terminates.
When a process terminates, the kernel notifies the parent by sending the SIGCHLD signal to
the parent.
Without wait, the parent may finish first leaving a zombie child, to be adopted by init
process
ALGORITHM
STEP 1: Create a child process using fork system call.
STEP 2: If return value is -1 then a. Print "Process creation unsuccessfull"
STEP 3: Terminate using exit system call.
STEP 4: If return value is > 0 then
i)Suspend parent process until child completes using wait system call
ii)Print "Parent starts"
iii)Print even numbers from 0–10 d. Print "Parent ends"
STEP 5: If return value is 0 then
i) Print "Child starts"
ii)Print odd numbers from 0–10
iii)Print "Child ends"
STEP 6: Stop the program.
PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
main()
{
int i, status;
pid_tpid;
pid = fork();
if (pid< 0)
{
printf("\nProcess creation failure\n");
16
exit(-1);
}
else if(pid> 0)
{
wait(NULL);
printf ("\nParent starts\nEven Nos: ");
for (i=2;i<=10;i+=2)
printf ("%3d",i);
printf ("\nParent ends\n");
}
else if (pid == 0)
{
printf ("Child starts\nOdd Nos: ");
for (i=1;i<10;i+=2)
printf ("%3d",i);
printf ("\nChild ends\n");
}
}
OUTPUT
$ gccwait.c
$ ./a.out
Child starts
Odd Nos: 1 3 5 7 9
Child ends
Parent starts
Even Nos: 2 4 6 8 10
Parent ends
RESULT
Thus using wait system call zombie child processes were avoided.
17
EX.No.:2c DATE:
EXEC SYSTEM CALL
AIM
To load an executable program in a child processes exec system call.
execl()
The exec family of function (execl, execv, execle, execve, execlp, execvp) is used by the
child process to load a program and execute.
execl system call requires path, program name and null pointer
ALGORITHM
STEP 1: Create a child process using fork system call.
STEP 2: If return value is -1 then a. Print "Process creation unsuccessfull"
STEP 3: Terminate using exit system call.
STEP 4: If return value is > 0 then
i) Suspend parent process until child completes using wait system call
ii) Print "Parent starts"
iii) Print even numbers from 0–10 d. Print "Parent ends"
STEP 5: If return value is 0 then
i) Print "Child starts"
ii) Print odd numbers from 0–10
iii) Print "Child ends"
STEP 6: Stop the program.
PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
main()
{
pid_tpid;
switch(pid = fork())
{
case -1:
perror("Fork failed");
exit(-1);
case 0:
printf("Child process\n");
execl("/bin/date", "date", 0);
exit(0);
default:
wait(NULL);
18
printf("Child Terminated\n");
exit(0);
}
}
OUTPUT
$ gccexec.c
$ ./a.out
Child process
Sat Feb 23 17:46:59 IST 2013
Child Terminated
RESULT
Thus the child process loads a binary executable file into its address space..
19
EX.No.:2d DATE:
STAT SYSTEM CALL
AIM
To display file status using stat system call.
exit()
The exit system call is used to terminate a process either normally or abnormally
Closes all standard I/O streams.
stat()
The stat system call is used to return information about a file as a structure.
ALGORITHM
STEP 1: Get filename as command line argument.
STEP 2: If filename does not exist then stop.
STEP 3: Call stat system call on the filename that returns a structure
STEP 4: Display members st_uid, st_gid, st_blksize, st_block, st_size, st_nlink, etc.,
STEP 5: Convert time members such as st_atime, st_mtime into time using ctimefunction
STEP 6: Compare st_mode with mode constants such as S_IRUSR, S_IWGRP, S_IXOTH and
display file permissions.
STEP 7: Stop the program.
PROGRAM
#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char*argv[])
{
struct stat file;
int n;
if (argc != 2)
{
printf("Usage: ./a.out<filename>\n");
exit(-1);
}
if ((n = stat(argv[1], &file)) == -1)
{
perror(argv[1]);
20
exit(-1);
}
printf("User id : %d\n", file.st_uid);
printf("Group id : %d\n", file.st_gid);
printf("Block size : %d\n", file.st_blksize);
printf("Blocks allocated : %d\n", file.st_blocks);
printf("Inode no. : %d\n", file.st_ino);
printf("Last accessed : %s", ctime(&(file.st_atime)));
printf("Last modified : %s", ctime(&(file.st_mtime)));
printf("File size : %d bytes\n", file.st_size);
printf("No. of links : %d\n", file.st_nlink);
printf("Permissions : ");
printf( (S_ISDIR(file.st_mode)) ? "d" : "-");
printf( (file.st_mode& S_IRUSR) ? "r" : "-");
printf( (file.st_mode& S_IWUSR) ? "w" : "-");
printf( (file.st_mode& S_IXUSR) ? "x" : "-");
printf( (file.st_mode& S_IRGRP) ? "r" : "-");
printf( (file.st_mode& S_IWGRP) ? "w" : "-");
printf( (file.st_mode& S_IXGRP) ? "x" : "-");
printf( (file.st_mode& S_IROTH) ? "r" : "-");
printf( (file.st_mode& S_IWOTH) ? "w" : "-");
printf( (file.st_mode& S_IXOTH) ? "x" : "-");
printf("\n");
if(file.st_mode& S_IFREG)
printf("File type : Regular\n");
if(file.st_mode& S_IFDIR)
printf("File type : Directory\n");
}
OUTPUT
$ gccstat.c
$ ./a.outfork.c
User id : 0
Group id : 0
Block size : 4096
Blocks allocated : 8
Inodeno. : 16627
21
Last accessed : Fri Feb 22 21:57:09 2013
Last modified : Fri Feb 22 21:56:13 2013
File size : 591 bytes
No. of links : 1
Permissions : -rw-r--r—
File type : Regular
RESULT
Thus attributes of a file is displayed using stat system call.
22
EX.No.:2e DATE:
READDIR SYSTEM CALL
AIM
To display directory contents using readdir system call.
ALGORITHM
STEP 1: Get directory name as command line argument.
STEP 2: If directory does not exist then stop.
STEP 3: Open the directory using opendir system call that returns a structure
STEP 4: Read the directory using readdir system call that returns a structure
STEP 5: Display d_name member for each entry.
STEP 6: Close the directory using closedir system call.
STEP 7: Stop the program.
PROGRAM
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
main(int argc, char *argv[])
{
struct dirent *dptr;
DIR *dname;
if (argc != 2)
{
printf("Usage: ./a.out<dirname>\n");
exit(-1);
}
if((dname = opendir(argv[1])) == NULL)
{
perror(argv[1]);
exit(-1);
}
23
while(dptr=readdir(dname))
printf("%s\n", dptr->d_name);
closedir(dname);
}
OUTPUT
$ gccdirlist.c
$ ./a.outvijai
wait.c
a.out
..
stat.c
dirlist.c
fork.c
.
exec.c
RESULT
Thus files and subdirectories in the directory was listed that includes hidden files.
24
EX.No.:2f DATE:
OPEN SYSTEM CALL
AIM
To create a file and to write contents.
open()
Used to open an existing file for reading/writing or to create a new file.
Returns a file descriptor whose value is negative on error.
The mandatory flags are O_RDONLY, O_WRONLY and O_RDWR
Optional flags include O_APPEND, O_CREAT, O_TRUNC, etc
The flags are ORed.
The mode specifies permissions for the file
creat()
Used to create a new file and open it for writing.
It is replaced with open() with flags O_WRONLY|O_CREAT | O_TRUNC
ALGORITHM
STEP 1: Declare a character buffer buf to store 100 bytes.
STEP 2: Get the new filename as command line argument.
STEP 3: Create a file with the given name using open system call with O_CREAT and
O_TRUNCoptions.
STEP 4: Check the file descriptor.
a) If file creation is unsuccessful, then stop.
STEP 5: Get input from the console until user typesCtrl+D
a) Read 100 bytes (max.) from console and store onto buf using read system call
b) Write length of buf onto file using write system call.
STEP 6: Close the file using close system call.
STEP 7: Stop the program.
PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
main(int argc, char *argv[])
{
int fd, n, len;
char buf[100];
25
if (argc != 2)
{
printf("Usage: ./a.out<filename>\n");
exit(-1);
}
fd = open(argv[1], O_WRONLY|O_CREAT|O_TRUNC, 0644);
if(fd< 0)
{
printf("File creation problem\n");
exit(-1);
}
OUTPUT
$ gccfcreate.c
$ ./a.outhello
File I/O
Open system call is used to either open or create a file.
creat system call is used to create a file. It is seldom used.
^D
RESULT
Thus a file has been created with input from the user. The process can be verified by using cat
command.
26
EX.No.:2g DATE:
READ SYSTEM CALL
AIM
To read the given file and to display file contents.
read()
Reads no. of bytes from the file or from the terminal.
If read is successful, it returns no. of bytes read.
The file offset is incremented by no. of bytes read.
If end-of-file is encountered, it returns 0.
ALGORITHM
STEP 1: Declare a character buffer buf to store 100 bytes.
STEP 2: Get existing filename as command line argument.
STEP 3: Open the file for reading using open system call with O_RDONLY option.
STEP 4: Check the file descriptor.
a) If file does not exist, then stop.
STEP 5: Read until end-of-file using read system call.
a) Read 100 bytes (max.) from file and print it
STEP 6: Close the file using close system call.
STEP 7: Stop the program.
PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
main(int argc, char *argv[])
{
int fd,i;
char buf[100];
if (argc< 2)
{
printf("Usage: ./a.out<filename>\n");
exit(-1);
}
fd = open(argv[1], O_RDONLY);
if(fd == -1)
{
printf("%s file does not exist\n", argv[1]);
exit(-1);
27
}
printf("Contents of the file %s is : \n", argv[1]);
while(read(fd, buf, sizeof(buf)) > 0)
printf("%s", buf);
close(fd);
}
OUTPUT
$ gccfread.c
$ ./a.outhello
File I/O open system call is used to either open or create a file.
creat system call is used to create a file. It is seldom used.
RESULT
Thus the given file is read and displayed on the console. The process can be verified by using cat
command..
28
EX.No.:2h DATE:
ALGORITHM
STEP 1: Declare a character buffer buf to store 100 bytes.
STEP 2: Get exisiting filename as command line argument.
STEP 3: Create a file with the given name using open system call with O_APPEND option.
STEP 4: Check the file descriptor.
a) If value is negative, then stop.
STEP 5: Get input from the console until user typesCtrl+D
a) Read 100 bytes (max.) from console and store onto buf using read system call
b) Write length of buf onto file using write system call.
STEP 6: Close the file using close system call.
STEP 7: Stop the program.
PROGRAM
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
main(int argc, char *argv[])
{
int fd, n, len;
char buf[100];
if (argc != 2)
{
printf("Usage: ./a.out<filename>\n");
exit(-1);
29
}
fd = open(argv[1], O_APPEND|O_WRONLY|O_CREAT, 0644);
if (fd< 0)
{
perror(argv[1]);
exit(-1);
}
while((n = read(0, buf, sizeof(buf))) > 0)
{
len = strlen(buf);
write(fd, buf, len);
}
close(fd);
}
OUTPUT
$ gccfappend.c
$ ./a.outhello
read system call is used to read from file or console
write system call is used to write to file.
^D
RESULT
Thus contents have been written to end of the file. The process can be verified by using cat
command.
30
EX.No.:3a DATE:
LS COMMAND
AIM
To simulate ls command using UNIX system calls.
ALGORITHM
STEP 1: Store path of current working directory using getcwd system call.
STEP 2: Scan directory of the stored path using scandir system call and sort the resultant array of
structure.
STEP 3: Display dname member for all entries if it is not a hidden file.
STEP 4: Stop the program.
PROGRAM
#include <stdio.h>
#include <dirent.h>
main()
{
struct dirent **namelist;
int n,i;
char pathname[100];
getcwd(pathname);
n = scandir(pathname, &namelist, 0, alphasort);
if(n < 0)
printf("Error\n");
else
for(i=0; i<n; i++)
if(namelist[i]->d_name[0] != '.')
printf("%-20s", namelist[i]->d_name);
}
OUTPUT
$ gcclist.c -o list
$ ./list
a.out
cmdpipe.c consumer.c dirlist.c ex6a.c ex6b.c ex6c.c
31
RESULT
Thus a python program for First Come First Served Scheduling using Queue is executed
successfully.
32
EX.NO.:3b DATE:
GREP COMMAND
AIM
To simulate grep command using UNIX system call.
ALGORITHM
STEP 1: Get filename and search string as command-line argument.
STEP 2: Open the file in read-only mode using open system call.
STEP 3: If file does not exist, then stop.
STEP 4: Let length of the search string be n.
STEP 5: Read line-by-line until end-of-file
a. Check to find out the occurrence of the search string in a line by examining characters in
the range 1–n, 2–n+1, etc.
b. If search string exists, then print the line.
STEP 6: Close the file using close system call.
STEP 7: Stop.
PROGRAM
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
main(int argc,char *argv[])
{
FILE *fd;
char str[100];
char c;
int i, flag, j, m, k;
char temp[30];
if(argc != 3)
{
printf("Usage: gccmygrep.c –o mygrep\n");
printf("Usage: ./mygrep<search_text><filename>\n");
exit(-1);
}
fd = fopen(argv[2],"r");
if(fd == NULL)
{
33
printf("%s is not exist\n",argv[2]);
exit(-1);
}
while(!feof(fd))
{
i = 0;
while(1)
{
c = fgetc(fd);
if(feof(fd))
{
str[i++] = '\0';
break;
}
if(c == '\n')
{
str[i++] = '\0';
break;
}
str[i++] = c;
}
if(strlen(str) >= strlen(argv[1]))
for(k=0; k<=strlen(str)-strlen(argv[1]); k++)
{
for(m=0; m<strlen(argv[1]); m++)
temp[m] = str[k+m];
temp[m] = '\0';
if(strcmp(temp,argv[1]) == 0)
{
printf("%s\n",str);
break;
}
}
}
}
34
OUTPUT
$ gccmygrep.c -o mygrep
$ ./mygrepprintfdirlist.c
printf("Usage: ./a.out \n");
printf("%s\n", dptr->d_name);
RESULT
Thus the program simulates grep command by listing lines containing the search text.
35
EX.NO.:3c DATE:
CP COMMAND
AIM
To simulate cp command using UNIX system call.
ALGORITHM
STEP 1: Get source and destination filename as command-line argument.
STEP 2: Declare a buffer of size 1KB
STEP 3: Open the source file in readonly mode using open system call.
STEP 4: If file does not exist, then stop.
STEP 5: Create the destination file using creat system call.
STEP 6: If file cannot be created, then stop.
STEP 7: File copy is achieved as follows:
a. Read 1KB data from source file and store onto buffer using read system call.
b. Write the buffer contents onto destination file using write system call.
c. If end-of-file then step 8 else step 7a.
STEP 8: Close source and destination file using close system call.
STEP 9: Stop.
PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#define SIZE 1024
main(int argc, char *argv[])
{
int src, dst, nread;
char buf[SIZE];
if (argc != 3)
{
printf("Usage: gcccopy.c -o copy\n");
printf("Usage: ./copy <filename><newfile> \n");
exit(-1);
}
if ((src = open(argv[1], O_RDONLY)) == -1)
{
36
perror(argv[1]);
exit(-1);
}
if ((dst = creat(argv[2], 0644)) == -1)
{
perror(argv[1]);
exit(-1);
}
while ((nread = read(src, buf, SIZE)) > 0)
{
if (write(dst, buf, nread) == -1)
{
printf("can't write\n");
exit(-1);
}
}
close(src);
close(dst);
}
OUTPUT
$ gcccopy.c -o copy
$ ./copy hello hello.txt
RESULT
Thus a file is copied using file I/O. The cmp command can be used to verify that contents of both
file are same.
37
EX.NO.:3d DATE:
RM COMMAND
AIM
To simulate rm command using UNIX system call.
ALGORITHM
STEP 1: Get filename as command-line argument.
STEP 2: Open the file in read-only mode using read system call.
STEP 3: If file does not exist, then stop.
STEP 4: Close the file using close system call.
STEP 5: Delete the file using unlink system call.
STEP 6: Stop.
PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
main(int argc, char* argv[])
{
int fd;
if (argc != 2)
{
printf("Usage: gccdel.c -o del\n");
printf("Usage: ./del <filename>\n");
exit(-1);
}
fd = open(argv[1], O_RDONLY);
if (fd != -1)
{
close(fd);
unlink(argv[1]);
}
else
perror(argv[1]);
}
38
OUTPUT
$ gccdel.c -o del
$ ./del hello.txt
RESULT
Thus files can be deleted in a manner similar to rm command. The deletion of file can be verified
by using ls command.
39
EX.No.:4 DATE:
SHELL PROGRAMMING
AIM
To write simple shell scripts using shell programming fundamentals.
The activities of a shell are not restricted to command interpretation alone. The shell also has
rudimentary programming features. Shell programs are stored in a file (with extension .sh). Shell
programs run in interpretive mode. The original UNIX came with the Bourne shell (sh) and it is
universal even today. C shell (csh) and Korn shell (ksh) are also widely used. Linux offers Bash shell
(bash) as a superior alternative to Bourne shell.
PRELIMINARIES
STEP 1: Comments in shell script start with #.
STEP 2: Shell variables are loosely typed i.e. not declared. Variables in an expression or output
must be prefixed by $.
STEP 3: The read statement is shell's internal tool for making scripts interactive.
STEP 4: Output is displayed using echo statement.
STEP 5: Expressions are computed using the expr command. Arithmetic operators are + - * / %.
Meta characters * ( ) should be escaped with a \.
STEP 6: The shell scripts are executed
i) $ sh filename
Decision-making
Shell supports decision-making using if statement. The if statement like its counterpart in
programming languages has the following formats.
The set of relational operators are –eq –ne –gt –ge –lt –le and logical operators used in conditional
expression are –a –o !
Multi-way branching
40
The case statement is used to compare a variables value against a set of constants. If it matches a
constant, then the set of statements followed after ) is executed till a ;; is encountered. The optional
default block is indicated by *. Multiple constants can be specified in a single pattern separated by |.
case variable in
constant1)
statements ;;
constant2)
statements ;;
...
*)
statements
esac
Loops
Shell supports a set of loops such as for, while and until to execute a set of statements repeatedly.
The body of the loop is contained between do and done statement.
The for loop doesn't test a condition, but uses a list instead.
The while loop executes the statements as long as the condition remains true. while [ condition ] do
statements done The until loop complements the while construct in the sense that the statements are
executed as long as the condition remains false.
until [ condition ]
do
statements
done
41
t=$a
a=$b
b=$t
echo "A value is $a and B value is $b"
Output
$ sh swap.sh
Enter value for A : 12
Enter value for B : 23
Values after Swapping
A Value is 23 and B Value is 12
B) Farenheit to Centigrade Conversion
# Degree conversion – degconv.sh
read f
c=`expr \( $f - 32 \) \* 5 / 9`
Output
$ sh degconv.sh
Centigrade is : 100
C) Biggest of 3 numbers
# Biggest – big3:sh
echo -n "Give value for A B and C: "
read a b c
if [ $a -gt $b -a $a -gt $c ]
then
echo "A is the Biggest number"
elif [ $b -gt $c ]
then
echo "B is the Biggest number"
else echo "C is the Biggest number"
fi
Output
$ sh big3:sh
Give value for A B and C: 4 3 4
C is the Biggest number
42
D) Grade Determination
# Grade – grade.sh
echo -n "Enter the mark : "
read mark
if [ $mark -gt90 ]
then
echo "S Grade"
elif [ $mark -gt80 ]
then
echo "A Grade"
elif [ $mark -gt70 ]
then
echo "B Grade"
elif [ $mark -gt60 ]
then
echo "C Grade"
elif [ $mark -gt55 ]
then
then
else
fi
Output
$ sh grade.sh
C Grade
E) Vowel or Consonant
# Vowel - vowel.sh
echo -n "Key in a lower case character : "
read choice
case $choice in
a|e|i|o|u) echo "It's a Vowel";;
*) echo "It's a Consonant"
43
esac
Output
$ sh vowel.sh
It's a Vowel
F) Simple Calculator
# Arithmetic operations — calc.sh
echo -n "Enter the two numbers : "
read a b
echo " 1: Addition"
echo " 2: Subtraction"
echo " 3: Multiplication"
echo " 4: Division"
echo -n "Enter the option : "
read option
case $option in
1) c=`expr $a + $b`
echo "$a + $b = $c";;
2) c=`expr $a - $b`
echo "$a - $b = $c";;
3) c=`expr $a \* $b`
echo "$a * $b = $c";;
4) c=`expr $a / $b`
echo "$a / $b = $c";;
esac
Output
$ sh calc.sh
Enter the two numbers : 2 4
1: Addition
2: Subtraction
3: Multiplication
4: Division
Enter the option : 1
2+4=6
G) Multiplication Table
# Multiplication table – multable.sh
clear
44
echo -n "Which multiplication table? : "
read n
for x in 1 2 3 4 5 6 7 8 9 10
do
p=`expr $x \* $n`
echo -n "$n X $x = $p"
sleep 1
done
Output
$ sh multable.sh
6 X 1 = 6 6 X 2 = 12
……
H) Number Reverse
# To reverse a number – reverse.sh
echo -n "Enter a number : "
read n
rd=0
while [ $n -gt0 ]
do
rem=`expr $n % 10`
rd=`expr $rd \* 10 + $rem`
n=`expr $n / 10`
done
echo "Reversed number is $rd"
Output
$ sh reverse.sh
Enter a number : 234
Reversed number is 432
I) Prime Number
# Prime number – prime.sh
echo -n "Enter the number : "
read n
i=2
m=`expr $n / 2`
until [ $i -gt $m ]
do
q=`expr $n % $i`
if [ $q -eq0 ]
then
echo "Not a Prime number"
exit
45
fi
i=`expr $i + 1`
done
Output
$ sh prime.sh
Prime number
RESULT
Thus shell scripts were executed using different programming constructs.
46
EX. NO.:5a DATE:
FCFS SCHEDULING
AIM
To schedule snapshot of processes queued according to FCFS scheduling.
Process Scheduling
CPU scheduling is used in multiprogrammed operating systems.
By switching CPU among processes, efficiency of the system can be improved.
Some scheduling algorithms are FCFS, SJF, Priority, Round-Robin, etc.
Gantt chart provides a way of visualizing CPU scheduling and enables to understand
better.
First Come First Serve (FCFS)
Process that comes first is processed first
FCFS scheduling is non-preemptive
Not efficient as it results in long average waiting time.
Can result in starvation, if processes at beginning of the queue have long bursts.
ALGORITHM
STEP 1: Define an array of structure process with members pid, btime, wtime&ttime.
STEP 2: Get length of the ready queue, i.e., number of process (say n)
STEP 3: Obtain btime for each process.
STEP 4: The wtime for first process is 0.
STEP 5: Compute wtime and ttime for each process as:
a. wtimei+1 = wtimei + btimei
b. ttimei = wtimei + btimei
STEP 6: Compute average waiting time awat and average turnaround time atur
STEP 7: Display the btime, ttime and wtime for each process.
STEP 8: Display GANTT chart for the above scheduling
STEP 9: Display awat time and atur
STEP 10: Stop
PROGRAM
struct process
{
int pid;
int btime;
int wtime;
int ttime;
47
} p[10];
main()
{
int i,j,k,n,ttur,twat;
float awat,atur;
printf("Enter no. of process : ");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf("Burst time for process P%d (in ms) : ",(i+1));
scanf("%d", &p[i].btime);
p[i].pid = i+1;
}
p[0].wtime = 0;
for(i=0; i<n; i++)
{
p[i+1].wtime = p[i].wtime + p[i].btime;
p[i].ttime = p[i].wtime + p[i].btime;
}
ttur = twat = 0;
for(i=0; i<n; i++)
{
ttur += p[i].ttime;
twat += p[i].wtime;
}
awat = (float)twat / n;
atur = (float)ttur / n;
printf("\n FCFS Scheduling\n\n");
for(i=0; i<28; i++)
printf("-");
printf("\nProcess B-Time T-Time W-Time\n");
for(i=0; i<28; i++)
printf("-");
for(i=0; i<n; i++)
printf("\n P%d\t%4d\t%3d\t%2d",
p[i].pid,p[i].btime,p[i].ttime,p[i].wtime);
printf("\n");
48
for(i=0; i<28; i++)
printf("-");
printf("\n\nAverage waiting time : %5:2fms", awat);
printf("\nAverageturn around time : %5:2fms\n", atur);
printf("\n\nGANTT Chart\n");
printf("-");
for(i=0; i<(p[n-1].ttime + 2*n); i++)
printf("-");
printf("\n");
printf("|");
for(i=0; i<n; i++)
{
k = p[i].btime/2;
for(j=0; j<k; j++)
printf(" ");
printf("P%d",p[i].pid);
for(j=k+1; j<p[i].btime; j++)
printf(" ");
printf("|");
}
printf("\n");
printf("-");
for(i=0; i<(p[n-1].ttime + 2*n); i++)
printf("-");
printf("\n");
printf("0");
for(i=0; i<n; i++)
{
for(j=0; j<p[i].btime; j++)
printf(" ");
printf("%2d",p[i].ttime);
}
}
OUTPUT
Enter no. of process : 4
Burst time for process P1 (in ms) : 10
Burst time for process P2 (in ms) : 4
49
Burst time for process P3 (in ms) : 11
Burst time for process P4 (in ms) : 6
FCFS Scheduling
----------------------------
Process B-Time T-Time W-Time
----------------------------
P1 10 10 0
P2 4 14 10
P3 11 25 14
P4 6 31 25
----------------------------
Average waiting time : 12:25ms
Average turn aroundtime : 20.00ms
GANTT Chart
----------------------------------------
| P1 | P2 | P3 | P4 |
----------------------------------------
0 10 14 25 31
RESULT
Thus waiting time & turnaround time for processes based on FCFS scheduling was computed and
the average waiting time was determined..
50
EX.NO.:5b DATE:
SJF SCHEDULING
AIM
To schedule snapshot of processes queued according to SJF scheduling.
Shortest Job First (SJF)
Process that requires smallest burst time is processed first.
SJF can be preemptive or non–preemptive
When two processes require same amount of CPU utilization, FCFS is used to break the tie.
Generally efficient as it results in minimal average waiting time.
Can result in starvation, since long critical processes may not be processed.
ALGORITHM
STEP 1: Define an array of structure process with members pid, btime, wtime&ttime.
STEP 2: Get length of the ready queue, i.e., number of process (say n)
STEP 3: Obtain btime for each process.
STEP 4: Sort the processes according to their btime in ascending order. a. If two process have
same btime, then FCFS is used to resolve the tie.
STEP 5: The wtime for first process is 0.
STEP 6: Compute wtime and ttime for each process as:
a. wtimei+1 = wtimei + btimei
b. ttimei = wtimei + btimei
STEP 7: Compute average waiting time awat and average turn around time atur.
STEP 8: Display btime, ttime and wtime for each process.
STEP 9: Display GANTT chart for the above scheduling
STEP 10: Display awat and atur
STEP 11: Stop
PROGRAM
#include <stdio.h>
struct process
{
int pid;
int btime;
int wtime;
int ttime;
} p[10], temp;
51
main()
{
int i,j,k,n,ttur,twat;
float awat,atur;
printf("Enter no. of process : ");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf("Burst time for process P%d (in ms) : ",(i+1));
scanf("%d", &p[i].btime);
p[i].pid = i+1;
}
for(i=0; i<n-1; i++)
{
for(j=i+1; j<n; j++)
{
if((p[i].btime> p[j].btime) ||
(p[i].btime == p[j].btime&& p[i].pid> p[j].pid))
{
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
p[0].wtime = 0;
for(i=0; i<n; i++)
{
p[i+1].wtime = p[i].wtime + p[i].btime;
p[i].ttime = p[i].wtime + p[i].btime;
}
ttur = twat = 0;
for(i=0; i<n; i++)
{
ttur += p[i].ttime;
twat += p[i].wtime;
}
52
awat = (float)twat / n;
atur = (float)ttur / n;
printf("\n SJF Scheduling\n\n");
for(i=0; i<28; i++)
printf("-");
printf("\nProcess B-Time T-Time W-Time\n");
for(i=0; i<28; i++)
printf("-");
for(i=0; i<n; i++)
printf("\n P%-4d\t%4d\t%3d\t%2d",
p[i].pid,p[i].btime,p[i].ttime,p[i].wtime);
printf("\n");
for(i=0; i<28; i++)
printf("-");
printf("\n\nAverage waiting time : %5:2fms", awat);
printf("\nAverageturn around time : %5:2fms\n", atur);
printf("\n\nGANTT Chart\n");
printf("-");
for(i=0; i<(p[n-1].ttime + 2*n); i++)
printf("-");
printf("\n|");
for(i=0; i<n; i++)
{
k = p[i].btime/2;
for(j=0; j<k; j++)
printf(" ");
printf("P%d",p[i].pid);
for(j=k+1; j<p[i].btime; j++)
printf(" ");
printf("|");
}
printf("\n-");
for(i=0; i<(p[n-1].ttime + 2*n); i++)
printf("-");
printf("\n0");
for(i=0; i<n; i++)
{
53
for(j=0; j<p[i].btime; j++)
printf(" ");
printf("%2d",p[i].ttime);
}
}
OUTPUT
Enter no. of process : 5
Burst time for process P1 (in ms) : 10
Burst time for process P2 (in ms) : 6
Burst time for process P3 (in ms) : 5
Burst time for process P4 (in ms) : 6
Burst time for process P5 (in ms) : 9
SJF Scheduling
----------------------------
Process B-Time T-Time W-Time
----------------------------
P3 5 5 0
P2 6 11 5
P4 6 17 11
P5 9 26 17
P1 10 36 26
----------------------------
Average waiting time : 11:80ms
Average turn aroundtime : 19:00ms
GANTT Chart
-----------------------------------------------
| P3 | P2 | P4 | P5 | P1 |
-----------------------------------------------
0 5 11 17 26 36
RESULT
Thus waiting time & turnaround time for processes based on SJF scheduling was computed and
the average waiting time was determined..
54
EX.NO.:5c DATE:
PRIORITY SCHEDULING
AIM
To schedule snapshot of processes queued according to Priority scheduling.
Priority
Process that has higher priority is processed first.
Prioirty can be preemptive or non–preemptive
When two processes have same priority, FCFS is used to break the tie.
Can result in starvation, since low priority processes may not be processed.
ALGORITHM
STEP 1: Define an array of structure process with members pid, btime, pri, wtime&ttime.
STEP 2: Get length of the ready queue, i.e., number of process (say n)
STEP 3: Obtain btime and pri for each process.
STEP 4: Sort the processes according to their pri in ascending order.
a. If two process have same pri, then FCFS is used to resolve the tie.
STEP 5: The wtime for first process is 0.
STEP 6: Compute wtime and ttime for each process as:
a. wtimei+1 = wtimei + btimei
b. ttimei = wtimei + btimei
STEP 7: Compute average waiting time awat and average turn around time atur
STEP 8: Display the btime, pri, ttime and wtime for each process.
STEP 9: Display GANTT chart for the above scheduling
STEP 10: Display awat and atur
STEP 11: Stop
PROGRAM
#include <stdio.h>
struct process
{
int pid;
int btime;
int pri;
int wtime;
int ttime;
} p[10], temp;
main()
{
int i,j,k,n,ttur,twat;
55
float awat,atur;
printf("Enter no. of process : ");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf("Burst time for process P%d (in ms) : ", (i+1));
scanf("%d", &p[i].btime);
printf("Priority for process P%d : ", (i+1));
scanf("%d", &p[i].pri);
p[i].pid = i+1;
}
for(i=0; i<n-1; i++)
{
for(j=i+1; j<n; j++)
{
if((p[i].pri> p[j].pri) ||
(p[i].pri == p[j].pri&& p[i].pid> p[j].pid) )
{
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
p[0].wtime = 0;
for(i=0; i<n; i++)
{
p[i+1].wtime = p[i].wtime + p[i].btime;
p[i].ttime = p[i].wtime + p[i].btime;
}
ttur = twat = 0;
for(i=0; i<n; i++)
{
ttur += p[i].ttime;
twat += p[i].wtime;
}
56
awat = (float)twat / n;
atur = (float)ttur / n;
printf("\n\t Priority Scheduling\n\n");
for(i=0; i<38; i++)
printf("-");
printf("\nProcess B-Time Priority T-Time W-Time\n");
for(i=0; i<38; i++)
printf("-");
for (i=0; i<n; i++)
printf("\n P%-4d\t%4d\t%3d\t%4d\t%4d",
p[i].pid,p[i].btime,p[i].pri,p[i].ttime,p[i].wtime);
printf("\n");
for(i=0; i<38; i++)
printf("-");
printf("\n\nAverage waiting time : %5:2fms", awat);
printf("\nAverageturn around time : %5:2fms\n", atur);
printf("\n\nGANTT Chart\n");
printf("-");
for(i=0; i<(p[n-1].ttime + 2*n); i++)
printf("-");
printf("\n|");
for(i=0; i<n; i++)
{
k = p[i].btime/2;
for(j=0; j<k; j++)
printf(" ");
printf("P%d",p[i].pid);
for(j=k+1; j<p[i].btime; j++)
printf(" ");
printf("|");
}
printf("\n-");
for(i=0; i<(p[n-1].ttime + 2*n); i++)
printf("-");
printf("\n0");
for(i=0; i<n; i++)
57
{
for(j=0; j<p[i].btime; j++)
printf(" ");
printf("%2d",p[i].ttime);
}
}
OUTPUT
Enter no. of process : 5
Burst time for process P1 (in ms) : 10
Priority for process P1 : 3
Burst time for process P2 (in ms) : 7
Priority for process P2 : 1
Burst time for process P3 (in ms) : 6
Priority for process P3 : 3
Burst time for process P4 (in ms) : 13
Priority for process P4 : 4
Burst time for process P5 (in ms) : 5
Priority for process P5 : 2
Priority Scheduling
--------------------------------------------------------
Process B-Time Priority T-Time W-Time
--------------------------------------------------------
P2 7 1 7 0
P5 5 2 12 7
P1 10 3 22 12
P3 6 3 28 22
P4 13 4 41 28
--------------------------------------------------------
Average waiting time : 13:80ms
Average turn aroundtime : 22:00ms
GANTT Chart
----------------------------------------------------
| P2 | P5 | P1 | P3 | P4 |
----------------------------------------------------
0 7 12 22 28 41
58
RESULT
Thus waiting time & turnaround time for processes based on Priority scheduling was computed
and the average waiting time was determined.
59
EX.NO.:5d DATE:
AIM
To schedule snapshot of processes queued according to Round robin scheduling.
Round Robin
All processes are processed one by one as they have arrived, but in rounds.
Each process cannot take more than the time slice per round.
Round robin is a fair preemptive scheduling algorithm.
A process that is yet to complete in a round is preempted after the time slice and put at the end
of the queue.
When a process is completely processed, it is removed from the queue.
ALGORITHM
STEP 1: Get length of the ready queue, i.e., number of process (say n)
STEP 2: Obtain Burst time Bi for each processes Pi.
STEP 3: Get the time slice per round, say TS
STEP 4: Determine the number of rounds for each process.
STEP 5: The wait time for first process is 0.
STEP 6: If Bi > TS then process takes more than one round. Therefore turnaround and waiting
time should include the time spent for other remaining processes in the same round.
STEP 7: Calculate average waiting time and turn aroundtime
STEP 8: Display the GANTT chart that includes
a. order in which the processes were processed in progression of rounds
b. Turnaround time Ti for each process in progression of rounds.
STEP 9: Display the burst time, turnaround time and wait time for each process (in order of
roundsthey were processed).
STEP 10: Display average wait time and turnaround time
STEP 11: Stop
PROGRAM
#include <stdio.h>
main()
{
int i,x=-1,k[10],m=0,n,t,s=0;
int a[50],temp,b[50],p[10],bur[10],bur1[10];
int wat[10],tur[10],ttur=0,twat=0,j=0;
float awat,atur;
60
printf("Enter no. of process : ");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf("Burst time for process P%d : ", (i+1));
scanf("%d", &bur[i]);
bur1[i] = bur[i];
}
printf("Enter the time slice (in ms) : ");
scanf("%d", &t);
for(i=0; i<n; i++)
{
b[i] = bur[i] / t;
if((bur[i]%t) != 0)
b[i] += 1;
m += b[i];
}
printf("\n\n");
for(i=0; i<30; i++)
printf("-");
printf("\nProcess\tBurst\tTrnd\tWait\n");
for(i=0; i<30; i++)
printf("-");
for (i=0; i<n; i++)
printf("\nP%-4d\t%4d\t%4d\t%4d", p[i]+1, bur1[i],
tur[i],wat[i]);
printf("\n");
for(i=0; i<30; i++)
printf("-");
awat = (float)twat / n;
atur = (float)ttur / n;
printf("\n\nAverage waiting time : %.2f ms", awat);
printf("\nAverageturn around time : %.2f ms\n", atur);
}
63
OUTPUT
Enter no. of process : 5
Burst time for process P1 : 10
Burst time for process P2 : 29
Burst time for process P3 : 3
Burst time for process P4 : 7
Burst time for process P5 : 12
Enter the time slice (in ms) : 10
Round Robin Scheduling
GANTT Chart
--------------------------------------------------------------
P1 | P2 | P3 | P4 | P5 | P2 | P5 | P2 |
--------------------------------------------------------------
0 10 20 23 30 40 50 52 61
------------------------------
Process Burst Trnd Wait
------------------------------
P1 10 10 0
P2 29 61 32
P3 3 23 20
P4 7 30 23
P5 12 52 40
------------------------------
Average waiting time : 23:00 ms
Average turn aroundtime : 35:20 ms
RESULT
Thus waiting time and turnaround time for processes based on Round robin scheduling was
computed and the average waiting time was determined.
64
EX.NO.:6 DATE:
SEMAPHORE IMPLEMENTATION
AIM
To demonstrate the utility of semaphore in synchronization and multithreading.
Semaphore
The POSIX system in Linux has its own built-in semaphore library.
To use it, include semaphore.h. Compile the code by linking with -lpthread -lrt.
To lock a semaphore or wait, use the sem_wait function.
To release or signal a semaphore, use the sem_post function.
A semaphore is initialised by using sem_init(for processes or threads)
To declare a semaphore, the data type is sem_t..
ALGORITHM
STEP 1: 2 threads are being created, one 2 seconds after the first one.
STEP 2: But the first thread will sleep for 4 seconds after acquiring the lock.
STEP 3:Thus the second thread will not enter immediately after it is called, it will enter 4 – 2 = 2
secs after it is called.
STEP 4: Stop
PROGRAM
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
sem_tmutex;
void* thread(void* arg)
{
sem_wait(&mutex);
printf("\nEntered..\n");
sleep(4);
printf("\nJust Exiting...\n");
sem_post(&mutex);
}
int main()
{
sem_init(&mutex, 0, 1);
pthread_t t1,t2;
65
pthread_create(&t1,NULL,thread,NULL);
sleep(2);
pthread_create(&t2,NULL,thread,NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
sem_destroy(&mutex);
return 0;
}
OUTPUT
$ gccsem.c -lpthread
$ ./a.out
Entered..
Just Exiting...
Entered..
Just Exiting...
RESULT
Thus semaphore implementation has been demonstrated..
66
EX.NO.:7a DATE:
FIBONACCI & PRIME NUMBER
AIM
To generate 25 fibonacci numbers and determine prime amongst them using pipe.
Interprocess Communication
Inter-Process communication (IPC), is the mechanism whereby one process can communicate
with another process, i.e exchange data.
IPC in linux can be implemented using pipe, shared memory, message queue, semaphore,
signal or sockets.
Pipe
Pipes are unidirectional byte streams which connect the standard output from one process into
the standard input of another process.
A pipe is created using the system call pipe that returns a pair of file descriptors.
The descriptor pfd[0] is used for reading and pfd[1] is used for writing.
Can be used only between parent and child processes.
ALGORITHM
STEP 1: Declare a array to store fibonacci numbers
STEP 2:Decalre a array pfd with two elements for pipe descriptors.
STEP 3: Create pipe on pfd using pipe function call.
a. If return value is -1 then stop
STEP 4: Using fork system call, create a child process.
STEP 5: Let the child process generate 25 fibonacci numbers and store them in a array.
STEP 6: Write the array onto pipe using write system call.
STEP 7: Block the parent till child completes using wait system call.
STEP 8: Store fibonacci nos. written by child from the pipe in an array using read system call
STEP 9: Inspect each element of the fibonacci array and check whether they are prime
a. If prime then print the fibonacci term.
STEP 10: Stop
PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
main()
{
pid_tpid;
int pfd[2];
67
int i,j,flg,f1,f2,f3;
static unsigned int ar[25],br[25];
if(pipe(pfd) == -1)
{
printf("Error in pipe");
exit(-1);
}
pid=fork();
if (pid == 0)
{
printf("Child process generates Fibonacci series\n" );
f1 = -1;
f2 = 1;
for(i = 0;i < 25; i++)
{
f3 = f1 + f2;
printf("%d\t",f3);
f1 = f2;
f2 = f3;
ar[i] = f3;
}
write(pfd[1],ar,25*sizeof(int));
}
else if (pid> 0)
{
wait(NULL);
read(pfd[0], br, 25*sizeof(int));
printf("\nParent prints Fibonacci that are Prime\n");
for(i = 0;i < 25; i++)
{
flg = 0;
if (br[i] <= 1)
flg = 1;
for(j=2; j<=br[i]/2; j++)
{
if (br[i]%j == 0)
{
68
flg=1;
break;
}
}
if (flg == 0)
printf("%d\t", br[i]);
}
printf("\n");
}
else
{
printf("Process creation failed");
exit(-1);
}
}
OUTPUT
$ gccfibprime.c
$ ./a.out
Child process generates Fibonacci series
0 1 1 2 3 5 8 13 21 34 55 89
144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657
46368
Parent prints Fibonacci that are Prime
2 3 5 13 89 233 1597 28657
RESULT
Thusfibonacci numbers that are prime is determined using IPC pipe.
69
EX.NO.:7b DATE:
WHO | WC -l
AIM
To determine number of users logged in using pipe.
ALGORITHM
STEP 1:Decalre a array pfd with two elements for pipe descriptors.
STEP 2: Create pipe on pfd using pipe function call.
a. If return value is -1 then stop
STEP 3: Using fork system call, create a child process.
STEP 4: Free the standard output (1) using close system call to redirect the output to pipe.
STEP 5: Make a copy of write end of the pipe using dup system call.
STEP 6: Execute who command using execlp system call.
STEP 7: Free the standard input (0) using close system call in the other process.
STEP 8: Make a close of read end of the pipe using dup system call.
STEP 9: Execute wc –l command using execlp system call.
STEP 10: Stop
PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int pfds[2];
pipe(pfds);
if (!fork())
{
close(1);
dup(pfds[1]);
close(pfds[0]);
execlp("who", "who", NULL);
}
else
{
close(0);
dup(pfds[0]);
close(pfds[1]);
70
execlp("wc", "wc", "-l", NULL);
}
}
OUTPUT
$ gcccmdpipe.c
$ ./a.out
15
RESULT
Thus standard output of who is connected to standard input of wc using pipe to compute number
of users logged in.
71
EX.NO.:7c DATE:
CHAT MESSAGING
AIM
To exchange message between server and client using message queue.
Message Queue
A message queue is a linked list of messages stored within the kernel
A message queue is identified by a unique identifier Every message has a positive long
integer type field, a non-negative length, and the actual data bytes.
The messages need not be fetched on FCFS basis. It could be based on type field.
ALGORITHM
SERVER
STEP 1:Decalre a structure mesgq with type and text fields.
STEP 2: Initialize key to 2013 (some random value).
STEP 3: Create a message queue using msgget with key & IPC_CREAT as parameter.
a. If message queue cannot be created then stop.
STEP 4: Initialize the message type member of mesgq to 1:
STEP 5: Do the following until user typesCtrl+D
a. Get message from the user and store it in text member.
b. Delete the newline character in text member.
c. Place message on the queue using msgsend for the client to read.
d. Retrieve the response message from the client using msgrcvfunction
e. Display the text contents.
STEP 6: Remove message queue from the system using msgctl with IPC_RMID as parameter.
STEP 7: Stop
CLIENT
STEP 1:Decalre a structure mesgq with type and text fields.
STEP 2: Initialize key to 2013 (same value as in server).
STEP 3: Open the message queue using msgget with key as parameter.
a. If message queue cannot be opened then stop.
STEP 4: Do while the message queue exists
a. Retrieve the response message from the server using msgrcvfunction
b. Display the text contents.
c. Get message from the user and store it in text member.
d. Delete the newline character in text member.
e. Place message on the queue using msgsend for the server to read.
STEP 5: Print "Server Disconnected".
STEP 6: Stop
72
PROGRAM
Server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct mesgq
{
long type;
char text[200];
} mq;
main()
{
int msqid, len;
key_t key = 2013;
if((msqid = msgget(key, 0644|IPC_CREAT)) == -1)
{
perror("msgget");
exit(1);
}
74
OUTPUT
Server
$ gccsrvmsg.c -o srvmsg
$ ./srvmsg
Enter text, ^D to quit:
hi
From Client: "hello"
Where r u?
From Client: "I'm where i am"
bye
From Client: "ok"
^D
Client
$ gccclimsg.c -o climsg
$ ./climsg
Client ready:
From Server: "hi"
hello
From Server: "Where r u?"
I'm where iam
From Server: "bye"
ok
Server Disconnected
RESULT
Thus chat session between client and server was done using message queue.
75
EX.NO.:7d DATE:
SHARED MEMORY
AIM
To demonstrate communication between process using shared memory.
Shared memory
Two or more processes share a single chunk of memory to communicate randomly.
Semaphores are generally used to avoid race condition amongst processes.
Fastest amongst all IPCs as it does not require any system call.
It avoids copying data unnecessarily.
ALGORITHM
Server
STEP 1: Initialize size of shared memory shmsize to 27:
STEP 2: Initialize key to 2013 (some random value).
STEP 3: Create a shared memory segment using shmget with key & IPC_CREAT as parameter.
a. If shared memory identifier shmid is -1, then stop.
STEP 4: Display shmid.
STEP 5: Attach server process to the shared memory using shmmat with shmid as parameter.
a. If pointer to the shared memory is not obtained, then stop.
STEP 6: Clear contents of the shared region using memset function.
STEP 7: Write a–z onto the shared memory.
STEP 8: Wait till client reads the shared memory contents
STEP 9:Detatch process from the shared memory using shmdt system call.
STEP 10: Remove shared memory from the system using shmctl with IPC_RMID argument
STEP 11: Stop
Client
1: Initialize size of shared memory shmsize to 27:
2: Initialize key to 2013 (same value as in server).
3: Obtain access to the same shared memory segment using same key.
a. If obtained then display the shmid else print "Server not started"
4: Attach client process to the shared memory using shmmat with shmid as parameter.
a. If pointer to the shared memory is not obtained, then stop.
5: Read contents of shared memory and print it.
6: After reading, modify the first character of shared memory to '*'
7: Stop
76
PROGRAM
Server
#include <stdio.h>
#include <stdlib.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define shmsize 27
main()
{
char c;
int shmid;
key_t key = 2013;
char *shm, *s;
#define shmsize 27
main()
{
int shmid;
key_t key = 2013;
char *shm, *s;
78
*shm = '*';
}
OUTPUT
Server
$ gccshms.c -o shms
$ ./shms
Shared memory id : 196611
Writing (a-z) onto shared memory
Client finished reading
Client
$ gccshmc.c -o shmc
$ ./shmc
Accessing shared memory id : 196611
Shared memory contents: abcdefghijklmnopqrstuvwxyz
RESULT
Thus contents written onto shared memory by the server process is read by the client process
79
EX.NO.:7e DATE:
PRODUCER CONSUMER PROBLEM
AIM
To synchronize producer and consumer processes using semaphore.
Semaphores
A semaphore is a counter used to synchronize access to a shared data amongst multiple
processes.
To obtain a shared resource, the process should:
a. Test the semaphore that controls the resource.
b. If value is positive, it gains access and decrements value of semaphore.
c. If value is zero, the process goes to sleep and awakes when value is > 0.
When a process relinquishes resource, it increments the value of semaphore by 1:
Producer-Consumer problem
A producer process produces information to be consumed by a consumer process
A producer can produce one item while the consumer is consuming another one.
With bounded-buffer size, consumer must wait if buffer is empty, whereas producer must wait
if buffer is full.
The buffer can be implemented using any IPC facility.
ALGORITHM
STEP 1: Create a shared memory segment BUFSIZE of size 1 and attach it.
STEP 2: Obtain semaphore id for variables empty, mutex and full using semget function.
STEP 3: Create semaphore for empty, mutex and full as follows:
a. Declare semun, a union of specific commands.
b. The initial values are: 1 for mutex, N for empty and 0 for full
c. Use semctl function with SETVAL command
STEP 4: Create a child process using fork system call.
a. Make the parent process to be the producer
b. Make the child process to the consumer
STEP 5: The producer produces 5 items as follows:
a. Call wait operation on semaphores empty and mutex using semop function.
b. Gain access to buffer and produce data for consumption
c. Call signal operation on semaphores mutex and full using semop function.
STEP 6: The consumer consumes 5 items as follows:
a. Call wait operation on semaphores full and mutex using semop function.
b. Gain access to buffer and consume the available data.
c. Call signal operation on semaphores mutex and empty using semop function.
STEP 7: Remove shared memory from the system using shmctl with IPC_RMID argument
STEP 8: Stop
80
PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define N 5
#define BUFSIZE 1
#define PERMS 0666
int *buffer;
int nextp = 0, nextc = 0;
int mutex, full, empty; /* semaphore variables */
void producer()
{
int data;
if(nextp == N)
nextp = 0;
printf("Enter data for producer to produce : ");
scanf("%d",(buffer + nextp));
nextp++;
}
void consumer()
{
int g;
if(nextc == N)
nextc = 0;
g = *(buffer + nextc++);
printf("\nConsumer consumes data %d", g);
}
void sem_op(int id, int value)
{
struct sembufop;
int v;
op.sem_num = 0;
op.sem_op = value;
81
op.sem_flg = SEM_UNDO;
if((v = semop(id, &op, 1)) < 0)
printf("\nError executing semop instruction");
}
void sem_create(int semid, int initval)
{
int semval;
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
} s;
s.val = initval;
if((semval = semctl(semid, 0, SETVAL, s)) < 0)
printf("\nError in executing semctl");
}
void sem_wait(int id)
{
int value = -1;
sem_op(id, value);
}
void sem_signal(int id)
{
int value = 1;
sem_op(id, value);
}
main()
{
int shmid, i;
pid_tpid;
if((shmid = shmget(1000, BUFSIZE, IPC_CREAT|PERMS)) < 0)
{
printf("\nUnable to create shared memory");
return;
}
if((buffer = (int*)shmat(shmid, (char*)0, 0)) == (int*)-1)
82
{
printf("\nShared memory allocation error\n");
exit(1);
}
if((mutex = semget(IPC_PRIVATE, 1, PERMS|IPC_CREAT)) == -1)
{
printf("\nCan't create mutex semaphore");
exit(1);
}
if((empty = semget(IPC_PRIVATE, 1, PERMS|IPC_CREAT)) == -1)
{
printf("\nCan't create empty semaphore");
exit(1);
}
if((full = semget(IPC_PRIVATE, 1, PERMS|IPC_CREAT)) == -1)
{
printf("\nCan't create full semaphore");
exit(1);
}
sem_create(mutex, 1);
sem_create(empty, N);
sem_create(full, 0);
if((pid = fork()) < 0)
{
printf("\nError in process creation");
exit(1);
}
else if(pid> 0)
{
for(i=0; i<N; i++)
{
sem_wait(empty);
sem_wait(mutex);
producer();
sem_signal(mutex);
sem_signal(full);
}
83
}
else if(pid == 0)
{
for(i=0; i<N; i++)
{
sem_wait(full);
sem_wait(mutex);
consumer();
sem_signal(mutex);
sem_signal(empty);
}
printf("\n");
}
}
OUTPUT
$ gccpcsem.c
$ ./a.out
Enter data for producer to produce : 5
Enter data for producer to produce : 8
Consumer consumes data 5
Enter data for producer to produce : 4
Consumer consumes data 8
Enter data for producer to produce : 2
Consumer consumes data 4
Enter data for producer to produce : 9
Consumer consumes data 2
Consumer consumes data 9
RESULT
Thus synchronization between producer and consumer process for access to a shared memory
segment is implemented.
84
EX.NO.:8 DATE:
BANKERS ALGORITHM FOR DEADLOCK AVOIDANCE
AIM
To implement deadlock avoidance by using Banker’s Algorithm.
ALGORITHM
STEP 1: Start the program.
STEP 8: If the new request comes then check that the system is in safety or not if we allow the
request.
STEP 9: Stop
PROGRAM
#include<stdio.h>
#include<stdio.h>
main()
{
int r[1][10], av[1][10];
int all[10][10], max[10][10], ne[10][10], w[10],safe[10];
int i=0, j=0, k=0, l=0, np=0, nr=0, count=0, cnt=0;
printf("enter the number of processes in a system");
scanf("%d", &np);
printf("enter the number of resources in a system");
scanf("%d",&nr);
for(i=1; i<=nr; i++)
{
printf("Enter no. of instances of resource R%d " ,i);
scanf("%d", &r[0][i]);
85
av[0][i] = r[0][i];
}
for(i=1; i<=np; i++)
for(j=1; j<=nr; j++)
all[i][j] = ne[i][j] = max[i][j] = w[i]=0;
printf("Enter the allocation matrix");
for(i=1; i<=np; i++)
{
for(j=1; j<=nr; j++)
{
scanf("%d", &all[i][j]);
av[0][j] = av[0][j] - all[i][j];
}
}
printf("Enter the maximum matrix");
for(i=1; i<=np; i++)
{
for(j=1; j<=nr; j++)
{
scanf("%d",&max[i][j]);
}
}
for(i=1; i<=np; i++)
{
for(j=1; j<=nr; j++)
{
ne[i][j] = max[i][j] - all[i][j];
}
}
for(i=1; i<=np; i++)
{
printf("pocessP%d", i);
for(j=1; j<=nr; j++)
{
printf("\n allocated %d\t",all[i][j]);
printf("maximum %d\t",max[i][j]);
printf("need %d\t",ne[i][j]);
86
}
printf("\n_________________________\n");
}
printf("\nAvailability ");
for(i=1; i<=nr; i++)
printf("R%d %d\t", i, av[0][i]);
printf("\n____________");
printf("\n safe sequence");
for(count=1; count<=np; count++)
{
for(i=1; i<=np; i++)
{
cnt = 0;
for(j=1; j<=nr; j++)
{
if(ne[i][j] <= av[0][j] && w[i]==0)
cnt++;
}
if(cnt == nr)
{
k++;
safe[k] = i;
for(l=1; l<=nr; l++)
av[0][l] = av[0][l] + all[i][l];
printf("\n P%d ",safe[k]);
printf("\t Availability ");
for(l=1; l<=nr; l++)
printf("R%d %d\t", l, av[0][l]);
w[i]=1;
}
}
}
}
OUTPUT
enter the number of processes in a system 3
enter the number of resources in a system 3
87
enter no. of instances of resource R1 10
enter no. of instances of resource R2 7
enter no. of instances of resource R3 7
Enter the allocation matrix
321
112
412
Enter the maximum matrix
444
345
524
pocess P1
allocated 3 maximum 4 need 1
allocated 2 maximum 4 need 2
allocated 1 maximum 4 need 3
_________________________
pocess P2
allocated 1 maximum 3 need 2
allocated 1 maximum 4 need 3
allocated 2 maximum 5 need 3
_________________________
pocess P3
allocated 4 maximum 5 need 1
allocated 1 maximum 2 need 1
allocated 2 maximum 4 need 2
_________________________
Availability R1 2 R2 3 R3 2
____________
safe sequence
P3 Availability R1 6 R2 4 R3 4
P1 Availability R1 9 R2 6 R3 5
P2 Availability R1 10 R2 7 R3 7
RESULT
Thus bankers algorithm for dead lock avoidance was executed successfully.
88
EX.NO.:9 DATE:
DEAD LOCK PREVENTION
AIM
To determine whether the process and their request for resources are in a deadlocked state.
ALGORITHM
STEP 1: Mark each process that has a row in the Allocation matrix of all zeros.
STEP 2: Initialize a temporary vectorW to equal the Available vector.
STEP 3: Find an indexi such that processi is currently unmarked and the Ith row ofQ is less than
or equal to W . That is,Qik … Wk, for 1 … k … m . If no such row is found, terminate the
algorithm.
STEP 4: If such a row is found, mark processi and add the corresponding row of the 6:allocation
matrix to W . That is, setWk = Wk + Aik, for 1 … k … m . return to step 3:
PROGRAM
#include<stdio.h>
#include<stdlib.h>
int max[100][100];
int alloc[100][100];
int need[100][100];
int avail[100];
int n, r;
void input();
void show();
void cal();
main()
{
int i,j;
printf("Deadlock Detection Algo\n");
input();
show();
cal();
}
void input()
{
int i,j;
printf("Enter the no of Processes\t");
89
scanf("%d",&n);
printf("Enter the no of resource instances\t");
scanf("%d", &r);
printf("Enter the Max Matrix\n");
for(i=0; i<n; i++)
for(j=0; j<r; j++)
scanf("%d", &max[i][j]);
printf("Enter the Allocation Matrix\n");
for(i=0; i<n; i++)
for(j=0; j<r; j++)
scanf("%d", &alloc[i][j]);
printf("Enter the available Resources\n");
for(j=0;j<r;j++)
scanf("%d",&avail[j]);
}
void show()
{
int i, j;
printf("Process\t Allocation\t Max\t Available\t");
for(i=0; i<n; i++)
{
printf("\nP%d\t ", i+1);
for(j=0; j<r; j++)
{
printf("%d ", alloc[i][j]);
}
printf("\t");
for(j=0; j<r; j++)
{
printf("%d ", max[i][j]);
}
printf("\t");
if(i == 0)
{
for(j=0; j<r; j++)
printf("%d ", avail[j]);
}
90
}
}
void cal()
{
int finish[100], temp, need[100][100], flag=1, k, c1=0;
int dead[100];
int safe[100];
int i, j;
for(i=0; i<n; i++)
{
finish[i] = 0;
}
for(i=0; i<n; i++)
{
for(j=0; j<r; j++)
{
need[i][j]= max[i][j] - alloc[i][j];
}
}
while(flag)
{
flag=0;
for(i=0;i<n;i++)
{
int c=0;
for(j=0;j<r;j++)
{
if((finish[i]==0) && (need[i][j] <= avail[j]))
{
c++;
if(c == r)
{
for(k=0; k<r; k++)
{
avail[k] += alloc[i][j];
finish[i]=1;
flag=1;
91
}
if(finish[i] == 1)
{
i=n;
}
}
}
}
}
}
j = 0;
flag = 0;
for(i=0; i<n; i++)
{
if(finish[i] == 0)
{
dead[j] = i;
j++;
flag = 1;
}
}
if(flag == 1)
{
printf("\n\nSystem is in Deadlock and the Deadlock process are\n");
for(i=0;i<n;i++)
{
printf("P%d\t", dead[i]);
}
}
else
{
printf("\nNo Deadlock Occur");
}
}
92
OUTPUT
********** Deadlock Detection Algo ************
Enter the no of Processes 3
Enter the no of resource instances 3
Enter the Max Matrix
360
433
344
Enter the Allocation Matrix
333
203
124
Enter the available Resources 1 2 0
Process Allocation Max Available
P1 333 360 120
P2 203 433
P3 124 344
System is in Deadlock and the Deadlock process are
P0 P1 P2
RESULT
Thus using given state of information deadlocked process were determined.
93
EX.NO.:10 DATE:
THREADING AND SYNCHRONIZATION
AIM
To demonstrate threading and synchronization using mutex.
Description
Thread synchronization is defined as a mechanism which ensures that two or more
concurrent processes or threads do not simultaneously execute some particular program
segment known as critical section.
Processes’ access to critical section is controlled by using synchronization techniques.
When one thread starts executing the critical section (serialized segment of the program)
the other thread should wait until the first thread finishes.
If proper synchronization techniques are not applied, it may cause a race condition where
the values of variables may be unpredictable
Mutex is a lock that we set before using a shared resource and release after using it.
When the lock is set, no other thread can access the locked region of code. So this
ensures a synchronized access of shared resources in the code
ALGORITHM
STEP 1: Create two threads
STEP 2: Let the threads share a common resource, say counter
STEP 3: Even if thread2 si scheduled to start while thread was not done, access to shared
resource isnot done as it is locked by mutex
STEP 4: Once thread1 completes, thread2 starts execution
STEP 5: Stop
PROGRAM
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
pthread_ttid[2];
int counter;
pthread_mutex_tlock;
void* trythis(void *arg)
{
pthread_mutex_lock(&lock);
unsigned long i = 0;
counter += 1;
printf("\n Job %d has started\n", counter);
94
for(i=0; i<(0xFFFFFFFF);i++);
printf("\n Job %d has finished\n", counter);
pthread_mutex_unlock(&lock);
return NULL;
}
main()
{
int i = 0;
int error;
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("\n mutex init has failed\n");
return 1;
}
while(i< 2)
{
err = pthread_create(&(tid[i]), NULL, &trythis, NULL);
if (error != 0)
printf("\nThread can't be created :[%s]",strerror(error));
i++;
}
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
pthread_mutex_destroy(&lock);
return 0;
}
OUTPUT
$ gccfilename.c -lpthread
$ ./a.out
Job 1 started
Job 1 finished
Job 2 started
Job 2 finished
RESULT
Thus concurrent threads were synchronized using mutex lock.
95
EX.NO.:11a DATE:
FIRST FIT ALLOCATION
AIM
To allocate memory requirements for processes using first fit allocation.
Memory Management
The first-fit, best-fit, or worst-fit strategy is used to select a free hole from the set of
available holes.
First fit
Allocate the first hole that is big enough.
Searching starts from the beginning of set of holes.
ALGORITHM
STEP 1: Declare structures hole and process to hold information about set of holes and processes
respectively.
STEP 2: Get number of holes, say nh.
STEP 3: Get the size of each hole
STEP 4: Get number of processes, say np.
STEP 5: Get the memory requirements for each process.
STEP 6: Allocate processes to holes, by examining each hole as follows:
a. If hole size > process size then
i. Mark process as allocated to that hole.
ii. Decrement hole size by process size.
b. Otherwise check the next from the set of hole
STEP 7: Print the list of process and their allocated holes or unallocated status.
STEP 8: Print the list of holes, their actual and current availability.
STEP 9: Stop
PROGRAM
#include <stdio.h>
struct process
{
int size;
int flag;
int holeid;
} p[10];
struct hole
{
96
int size;
int actual;
} h[10];
main()
{
int i, np, nh, j;
printf("Enter the number of Holes : ");
scanf("%d", &nh);
for(i=0; i<nh; i++)
{
printf("Enter size for hole H%d : ",i);
scanf("%d", &h[i].size);
h[i].actual = h[i].size;
}
printf("\nEnter number of process : " );
scanf("%d",&np);
for(i=0;i<np;i++)
{
printf("enter the size of process P%d : ",i);
scanf("%d", &p[i].size);
p[i].flag = 0;
}
for(i=0; i<np; i++)
{
for(j=0; j<nh; j++)
{
if(p[i].flag != 1)
{
if(p[i].size<= h[j].size)
{
p[i].flag = 1;
p[i].holeid = j;
h[j].size -= p[i].size;
}
}
}
}
97
printf("\n\tFirst fit\n");
printf("\nProcess\tPSize\tHole");
for(i=0; i<np; i++)
{
if(p[i].flag != 1)
printf("\nP%d\t%d\tNot allocated", i, p[i].size);
else
printf("\nP%d\t%d\tH%d", i, p[i].size, p[i].holeid);
}
printf("\n\nHole\tActual\tAvailable");
for(i=0; i<nh ;i++)
printf("\nH%d\t%d\t%d", i, h[i].actual, h[i].size);
printf("\n");
}
OUTPUT
Enter the number of Holes : 5
Enter size for hole H0 : 100
Enter size for hole H1 : 500
Enter size for hole H2 : 200
Enter size for hole H3 : 300
Enter size for hole H4 : 600
Enter number of process : 4
enter the size of process P0 : 212
enter the size of process P1 : 417
enter the size of process P2 : 112
enter the size of process P3 : 426
First fit
Process PSize Hole
P0 212 H1
P1 417 H4
P2 112 H1
P3 426 Not allocated
Hole Actual Available
H0 100 100
H1 500 176
H2 200 200
98
H3 300 300
H4 600 183
RESULT
Thus processes were allocated memory using first fit method
99
EX.NO.:11b DATE:
BEST FIT ALLOCATION
AIM
To allocate memory requirements for processes using best fit allocation.
Best fit
Allocate the smallest hole that is big enough.
The list of free holes is kept sorted according to size in ascending order.
This strategy produces smallest leftover holes
ALGORITHM
STEP 1: Declare structures hole and process to hold information about set of holes and processes
respectively.
STEP 2: Get number of holes, say nh.
STEP 3: Get the size of each hole
STEP 4: Get number of processes, say np.
STEP 5: Get the memory requirements for each process.
STEP 6: Allocate processes to holes, by examining each hole as follows:
a. Sort the holes according to their sizes in ascending order
b. If hole size > process size then
i. Mark process as allocated to that hole.
ii. Decrement hole size by process size.
c. Otherwise check the next from the set of sorted hole
STEP 7: Print the list of process and their allocated holes or unallocated status.
STEP 8: Print the list of holes, their actual and current availability.
STEP 9: Stop
PROGRAM
#include <stdio.h>
struct process
{
int size;
int flag;
int holeid;
} p[10];
struct hole
{
int hid;
int size;
100
int actual;
} h[10];
main()
{
int i, np, nh, j;
void bsort(struct hole[], int);
printf("Enter the number of Holes : ");
scanf("%d", &nh);
for(i=0; i<nh; i++)
{
printf("Enter size for hole H%d : ",i);
scanf("%d", &h[i].size);
h[i].actual = h[i].size;
h[i].hid = i;
}
printf("\nEnter number of process : " );
scanf("%d",&np);
for(i=0;i<np;i++)
{
printf("enter the size of process P%d : ",i);
scanf("%d", &p[i].size);
p[i].flag = 0;
}
for(i=0; i<np; i++)
{
bsort(h, nh);
for(j=0; j<nh; j++)
{
if(p[i].flag != 1)
{
if(p[i].size<= h[j].size)
{
p[i].flag = 1;
p[i].holeid = h[j].hid;
h[j].size -= p[i].size;
}
}
101
}
}
printf("\n\tBest fit\n");
printf("\nProcess\tPSize\tHole");
for(i=0; i<np; i++)
{
if(p[i].flag != 1)
printf("\nP%d\t%d\tNot allocated", i, p[i].size);
else
printf("\nP%d\t%d\tH%d", i, p[i].size, p[i].holeid);
}
printf("\n\nHole\tActual\tAvailable");
for(i=0; i<nh ;i++)
printf("\nH%d\t%d\t%d", h[i].hid, h[i].actual,
h[i].size);
printf("\n");
}
void bsort(struct hole bh[], int n)
{
struct hole temp;
int i,j;
for(i=0; i<n-1; i++)
{
for(j=i+1; j<n; j++)
{
if(bh[i].size>bh[j].size)
{
temp = bh[i];
bh[i] = bh[j];
bh[j] = temp;
}
}
}
}
102
OUTPUT
Enter the number of Holes : 5
Enter size for hole H0 : 100
Enter size for hole H1 : 500
Enter size for hole H2 : 200
Enter size for hole H3 : 300
Enter size for hole H4 : 600
Enter number of process : 4
enter the size of process P0 : 212
enter the size of process P1 : 417
enter the size of process P2 : 112
enter the size of process P3 : 426
Best fit
Process PSize Hole
P0 212 H3
P1 417 H1
P2 112 H2
P3 426 H4
Hole Actual Available
H1 500 83
H3 300 88
H2 200 88
H0 100 100
H4 600 174
RESULT
Thus processes were allocated memory using best fit method.
103
EX.NO.:12 DATE:
PAGING TECHNIQUE
AIM
To determine physical address of a given page using page table..
ALGORITHM
STEP 1: Get process size
STEP 2:Compte no. of pages available and display it
STEP 3: Get relative address
STEP 4: Determine the corresponding page
STEP 5: Display page table
STEP 6: Display the physical address.
PROGRAM
#include <stdio.h>
#include <math.h>
main()
{
int size, m, n, pgno, pagetable[3]={5,6,7}, i, j, frameno;
double m1;
int ra=0, ofs;
printf("Enter process size (in KB of max 12KB):");
scanf("%d", &size);
m1 = size / 4;
n = ceil(m1);
printf("Total No. of pages: %d", n);
printf("\nEnter relative address (in hexa) \n");
scanf("%d", &ra);
pgno = ra / 1000;
ofs = ra % 1000;
printf("page no=%d\n", pgno);
printf("page table");
for(i=0;i<n;i++)
printf("\n %d [%d]", i, pagetable[i]);
frameno = pagetable[pgno];
printf("\nPhysical address: %d%d", frameno, ofs);
}
104
OUTPUT
Enter process size (in KB of max 12KB):12
Total No. of pages: 3
Enter relative address (in hexa):
2643
page no=2
page table
0 [5]
1 [6]
2 [7]
Physical address : 7643
RESULT
Thus physical address for the given logical address is determing using Paging technique.
105
EX.NO.:13a DATE:
FIFO PAGE REPLACEMNET
AIM
To implement demand paging for a reference string using FIFO method.
FIFO
Page replacement is based on when the page was brought into memory.
When a page should be replaced, the oldest one is chosen.
Generally, implemented using a FIFO queue.
Simple to implement, but not efficient.
Results in more page faults.
The page-fault may increase, even if frame size is increased (Belady's anomaly)
ALGORITHM
STEP 1: Get length of the reference string, say l.
STEP 2: Get reference string and store it in an array, say rs.
STEP 3: Get number of frames, say nf.
STEP 4:Initalize frame array upto length nf to -1:
STEP 5: Initialize position of the oldest page, say j to 0.
STEP 6: Initialize no. of page faults, say count to 0.
STEP 7: For each page in reference string in the given order, examine:
a. Check whether page exist in the frame array
b. If it does not exist then
i. Replace page in position j.
ii. Compute page replacement position as (j+1) modulus nf.
iii. Increment count by 1:
iv. Display pages in frame array.
STEP 8: Print count.
STEP 9: Stop.
PROGRAM
#include <stdio.h>
main()
{
int i,j,l,rs[50],frame[10],nf,k,avail,count=0;
printf("Enter length of ref. string : ");
scanf("%d", &l);
printf("Enter reference string :\n");
for(i=1; i<=l; i++)
scanf("%d", &rs[i]);
106
printf("Enter number of frames : ");
scanf("%d", &nf);
for(i=0; i<nf; i++)
frame[i] = -1;
j = 0;
printf("\nRef. str Page frames");
for(i=1; i<=l; i++)
{
printf("\n%4d\t", rs[i]);
avail = 0;
for(k=0; k<nf; k++)
if(frame[k] == rs[i])
avail = 1;
if(avail == 0)
{
frame[j] = rs[i];
j = (j+1) % nf;
count++;
for(k=0; k<nf; k++)
printf("%4d", frame[k]);
}
}
printf("\n\nTotal no. of page faults : %d\n",count);
}
OUTPUT
Enter length of ref. string : 20
Enter reference string :
123421562123763
Enter number of frames : 5
Ref. str Page frames
1 1 -1 -1 -1 -1
2 1 2 -1 -1 -1
3 1 2 3 -1 -1
4 1 2 3 4 -1
2
1
107
512345
662345
2
161345
261245
361235
761237
6
3
Total no. of page faults : 10
RESULT
Thus page replacement was implemented using FIFO algorithm.
108
EX.NO.:13b DATE:
LRU PAGE REPLACEMENT
AIM
To implement demand paging for a reference string using LRU method.
LRU
Pages used in the recent past are used as an approximation of future usage.
The page that has not been used for a longer period of time is replaced.
LRU is efficient but not optimal.
Implementation of LRU requires hardware support, such as counters/stack
ALGORITHM
STEP 1: Get length of the reference string, say len.
STEP 2: Get reference string and store it in an array, say rs.
STEP 3: Get number of frames, say nf.
STEP 4: Create access array to store counter that indicates a measure of recent usage.
STEP 5: Create a function arrmin that returns position of minimum of the given array.
STEP 6:Initalize frame array upto length nf to -1:
STEP 7: Initialize position of the page replacement, say j to 0.
STEP 8: Initialize freq to 0 to track page frequency
STEP 9: Initialize no. of page faults, say count to 0.
STEP 10: For each page in reference string in the given order, examine:
a. Check whether page exist in the frame array.
b. If page exist in memory then
i. Store incremented freq for that page position in access array.
c. If page does not exist in memory then
i. Check for any empty frames.
ii. If there is an empty frame,
Assign that frame to the page
Store incremented freq for that page position in access array.
Increment count.
iii. If there is no free frame then
Determine page to be replaced using arrmin function.
Store incremented freq for that page position in access array.
Increment count.
iv. Display pages in frame array.
STEP 11: Print count.
STEP 12: Stop
109
PROGRAM
#include <stdio.h>
int arrmin(int[], int);
main()
{
int i,j,len,rs[50],frame[10],nf,k,avail,count=0;
int access[10], freq=0, dm;
printf("Length of Reference string : ");
scanf("%d", &len);
printf("Enter reference string :\n");
for(i=1; i<=len; i++)
scanf("%d", &rs[i]);
printf("Enter no. of frames : ");
scanf("%d", &nf);
for(i=0; i<nf; i++)
frame[i] = -1;
j = 0;
printf("\nRef. str Page frames");
for(i=1; i<=len; i++)
{
printf("\n%4d\t", rs[i]);
avail = 0;
for(k=0; k<nf; k++)
{
if(frame[k] == rs[i])
{
avail = 1;
access[k] = ++freq;
break;
}
}
if(avail == 0)
{
dm = 0;
for(k=0; k<nf; k++)
{
if(frame[k] == -1)
110
dm = 1;
break;
}
if(dm == 1)
{
frame[k] = rs[i];
access[k] = ++freq;
count++;
}
else
{
j = arrmin(access, nf);
frame[j] = rs[i];
access[j] = ++freq;
count++;
}
for(k=0; k<nf; k++)
printf("%4d", frame[k]);
}
}
printf("\n\nTotal no. of page faults : %d\n", count);
}
int arrmin(int a[], int n)
{
int i, min = a[0];
for(i=1; i<n; i++)
if (min > a[i])
min = a[i];
for(i=0; i<n; i++)
if (min == a[i])
return i;
}
OUTPUT
Length of Reference string : 15
Enter reference string :
123421562123763
Enter no. of frames : 5
111
Ref. str Page frames
1 1 -1 -1 -1 -1
2 1 2 -1 -1 -1
3 1 2 3 -1 -1
4 1 2 3 4 -1
2
1
512345
612645
2
1
2
312635
712637
6
3
Total no. of page faults : 8
RESULT
Thus page replacement was implemented using LRU algorithm.
112
EX.NO.:14a DATE:
SINGLE LEVEL DIRECTORY
AIM
To organize files in a single level directory structure, I,e., without sub-directories
ALGORITHM
STEP 1: Get name of directory for the user to store all the files
STEP 2: Display menu
STEP 3: Accept choice
STEP 4: If choice =1 then
Accept filename without any collission
Store it in the directory
STEP 5: If choice =2 then
Accept filename
Remove filename from the directory array
STEP 6: If choice =3 then
Accept filename
Check for existence of file in the directory array
STEP 7: If choice =4 then List all files in the directory array
STEP 8: If choice =5 then
STEP 9:Stop
PROGRAM
#include <stdio.h>
#include <stdlib.h>
struct
{
char dname[10];
char fname[25][10];
int fcnt;
}dir;
main()
{
int i, ch;
char f[30];
dir.fcnt = 0;
printf("\nEnter name of directory -- ");
113
scanf("%s", dir.dname);
while(1)
{
printf("\n\n 1: Create File\t2: Delete File\t3: Search File \n4: Display Files\t5: Exit\nEnter your
choice--");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("\n Enter the name of the file -- ");
scanf("%s", dir.fname[dir.fcnt]);
dir.fcnt++;
break;
case 2:
printf("\n Enter the name of the file -- ");
scanf("%s", f);
for(i=0; i<dir.fcnt; i++)
{
if(strcmp(f, dir.fname[i]) == 0)
{
printf("File %s is deleted ",f);
strcpy(dir.fname[i], dir.fname[dir.fcnt-1]);
break;
}
}
if(i == dir.fcnt)
printf("File %s not found", f);
else
dir.fcnt--;
break;
case 3:
printf("\n Enter the name of the file -- ");
scanf("%s", f);
for(i=0; i<dir.fcnt; i++)
{
if(strcmp(f, dir.fname[i]) == 0)
{
114
printf("File %s is found ", f);
break;
}
}
if(i == dir.fcnt)
printf("File %s not found", f);
break;
case 4:
if(dir.fcnt == 0)
printf("\n Directory Empty");
else
{
printf("\n The Files are -- ");
for(i=0; i<dir.fcnt; i++)
printf("\t%s", dir.fname[i]);
}
break;
default:
exit(0);
}
}
getch();
}
OUTPUT
Enter name of directory -- CSE
1: Create File 2: Delete File 3: Search File
4: Display Files 5: Exit
Enter your choice -- 1
Enter the name of the file -- fcfs
1: Create File 2: Delete File 3: Search File
4: Display Files 5: Exit
Enter your choice -- 1
Enter the name of the file -- sjf
1: Create File 2: Delete File 3: Search File
4: Display Files 5: Exit
Enter your choice -- 1
Enter the name of the file -- lru
115
1: Create File 2: Delete File 3: Search File
4: Display Files 5: Exit
Enter your choice -- 3
Enter the name of the file -- sjf
File sjf is found
1: Create File 2: Delete File 3: Search File
4: Display Files 5: Exit Enter your choice -- 3
Enter the name of the file -- bank
File bank is not found
1: Create File 2: Delete File 3: Search File
4: Display Files 5: Exit
Enter your choice -- 4
The Files are -- fcfssjflrubank
1: Create File 2: Delete File 3: Search File
4: Display Files 5: Exit
Enter your choice -- 2
Enter the name of the file -- lru
File lru is deleted
RESULT
Thus files were organized into a single level directory.
116
EX.NO.:14b DATE:
TWO LEVEL DIRECTORY
AIM
To organize files as two-level directory with each user having his own user file directory (UFD)
ALGORITHM
STEP 1: Display menu
STEP 2: Accept choice
STEP 3: If choice =1 then
Accept directory name
Create an entry for that directory
STEP 4: If choice =2 then
Get directory name
If directory exist then accept filename without collision else report error
STEP 5: If choice =3 then
Get directory name
If directory exist then Get filename
If file exist in that directory then delete entry else report error
STEP 6: If choice =4 then
Get directory name
If directory exist then Get filename
If file exist in that directory then Display filename else report error
STEP 7: If choice =5 then Display files directory-wise
STEP 8: If choice =6 then Stop
PROGRAM
#include <stdio.h>
#include <stdlib.h>
struct
{
char dname[10], fname[10][10];
int fcnt;
}dir[10];
main()
{
int i, ch, dcnt, k;
char f[30], d[30];
dcnt=0;
117
while(1)
{
printf("\n\n 1: Create Directory\t 2: Create File\t 3:Delete File");
printf("\n 4: Search File \t \t 5: Display \t 6: Exit \nEnter your choice -- ");
scanf("%d", &ch);
switch(ch)
{
case 1:
printf("\n Enter name of directory -- ");
scanf("%s", dir[dcnt].dname);
dir[dcnt].fcnt = 0;
dcnt++;
printf("Directory created");
break;
case 2:
printf("\n Enter name of the directory -- ");
scanf("%s", d);
for(i=0; i<dcnt; i++)
if(strcmp(d,dir[i].dname) == 0)
{
printf("Enter name of the file -- ");
scanf("%s", dir[i].fname[dir[i].fcnt]);
dir[i].fcnt++;
printf("File created");
break;
}
if(i == dcnt)
printf("Directory %s not found",d);
break;
case 3:
printf("\nEnter name of the directory -- ");
scanf("%s", d);
for(i=0; i<dcnt; i++)
{
if(strcmp(d,dir[i].dname) == 0)
{
printf("Enter name of the file -- ");
118
scanf("%s", f);
for(k=0; k<dir[i].fcnt; k++)
{
if(strcmp(f, dir[i].fname[k]) == 0)
{
printf("File %s is deleted ", f);
dir[i].fcnt--;
strcpy(dir[i].fname[k],
dir[i].fname[dir[i].fcnt]);
gotojmp;
}
}
printf("File %s not found",f);
gotojmp;
}
}
printf("Directory %s not found",d);
jmp : break;
case 4:
printf("\nEnter name of the directory -- ");
scanf("%s", d);
for(i=0; i<dcnt; i++)
{
if(strcmp(d,dir[i].dname) == 0)
{
printf("Enter the name of the file -- ");
scanf("%s", f);
for(k=0; k<dir[i].fcnt; k++)
{
if(strcmp(f, dir[i].fname[k]) == 0)
{
printf("File %s is found ", f);
gotojmp1;
}
}
printf("File %s not found", f);
gotojmp1;
119
}
}
printf("Directory %s not found", d);
jmp1: break;
case 5:
if(dcnt == 0)
printf("\nNo Directory's ");
else
{
printf("\nDirectory\tFiles");
for(i=0;i<dcnt;i++)
{
printf("\n%s\t\t",dir[i].dname);
for(k=0;k<dir[i].fcnt;k++)
printf("\t%s",dir[i].fname[k]);
}
}
break;
default:
exit(0);
}
}
getch();
}
OUTPUT
Create Directory 2: Create File 3: Delete File 4: Search File 5: Display 6: Exit
Enter your choice -- 1
Enter name of directory -- CSE
Directory created
1:Create Directory 2: Create File 3: Delete File 4: Search File 5: Display 6: Exit
Enter your choice -- 1
Enter name of directory -- ECE
Directory created
1. Create Directory 2: Create File 3: Delete File 4: Search File 5: Display 6: Exit
Enter your choice -- 2
Enter name of the directory -- ECE
120
Enter name of the file -- amruth
File created
1. Create Directory 2: Create File 3: Delete File 4: Search File 5: Display 6: Exit
Enter your choice -- 2
Enter name of the directory -- CSE
Enter name of the file -- kowshik
File created
1. Create Directory 2: Create File 3: Delete File 4: Search File 5: Display 6: Exit
Enter your choice -- 2
Enter name of the directory -- CSE
Enter name of the file -- pranesh
File created
1. Create Directory 2: Create File 3: Delete File 4: Search File 5: Display 6: Exit
Enter your choice -- 2
Enter name of the directory -- ECE
Enter name of the file -- ajith
File created
1. Create Directory 2: Create File 3: Delete File 4: Search File 5: Display 6: Exit
Enter your choice -- 5
Directory Files
CSE kowshikpranesh
ECE amruthajith
1. Create Directory 2: Create File 3: Delete File 4: Search File 5: Display 6: Exit
Enter your choice -- 3
Enter name of the directory -- ECE
Enter name of the file -- ajith
File ajith is deleted
RESULT
Thus user files have been stored in their respective directories and retrieved easily.
121
EX.No.:15a DATE:
CONTIGUOUS ALLOCATION
AIM
To implement file allocation on free disk space in a contiguous manner.
File Allocation
The three methods of allocating disk space are:
1: Contiguous allocation
2: Linked allocation
3: Indexed allocation
Contiguous
Each file occupies a set of contiguous block on the disk.
The number of disk seeks required is minimal.
The directory contains address of starting block and number of contiguous block (length)
occupied.
Supports both sequential and direct access.
First / best fit is commonly used for selecting a hole.
ALGORITHM
STEP 1: Assume no. of blocks in the disk as 20 and all are free.
STEP 2: Display the status of disk blocks before allocation.
STEP 3: For each file to be allocated:
a. Get the filename, start address and file length
b. If start + length > 20, then goto step 2:
c. Check to see whether any block in the range (start, start + length-1) is allocated. If so, then go
to step 2:
d. Allocate blocks to the file contiguously from start block to start + length – 1:
STEP 4: Display directory entries.
STEP 5: Display status of disk blocks after allocation
STEP 6: Stop
PROGRAM
#include <stdio.h>
#include <string.h>
int num=0, length[10], start[10];
char fid[20][4], a[20][4];
void directory()
{
int i;
printf("\nFile Start Length\n");
for(i=0; i<num; i++)
122
printf("%-4s %3d %6d\n",fid[i],start[i],length[i]);
}
void display()
{
int i;
for(i=0; i<20; i++)
printf("%4d",i);
printf("\n");
for(i=0; i<20; i++)
printf("%4s", a[i]);
}
main()
{
int i,n,k,temp,st,nb,ch,flag;
char id[4];
for(i=0; i<20; i++)
strcpy(a[i], "");
printf("Disk space before allocation:\n");
display();
do
{
printf("\nEnter File name (max 3 char) : ");
scanf("%s", id);
printf("Enter start block : ");
scanf("%d", &st);
printf("Enter no. of blocks : ");
scanf("%d", &nb);
strcpy(fid[num], id);
length[num] = nb;
flag = 0;
RESULT
Thus contiguous allocation is done for files with the available free blocks.
125
EX.No.:15b DATE:
LINKED FILE ALLOCATION
AIM
To implement file allocation on free disk space in a linked file manner.
Linked
Each file is a linked list of disk blocks.
The directory contains a pointer to first and last blocks of the file.
The first block contains a pointer to the second one, second to third and so on.
File size need not be known in advance, as in contiguous allocation.
No external fragmentation.
Supports sequential access only.
Indexed
In indexed allocation, all pointers are put in a single block known as index block.
The directory contains address of the index block.
The ith entry in the index block points to ith block of the file.
Indexed allocation supports direct access.
It suffers from pointer overhead, i.e wastage of space in storing pointers
ALGORITHM
STEP 1: Get no. of files
STEP 2: Accept filenames and no. of blocks fo each file
STEP 3:Obtrain start block for each file
STEP 4: Obtain other blocks for each file
STEP 5: Check block availability before allocation
STEP 6: If block is unavailable then report error
STEP 7: Accept file name
STEP 8: Display linked file allocation blocks for that file
STEP 9: Stop
PROGRAM
#include <stdio.h>
#include <string.h>
main()
{
static int b[20], i, j, blocks[20][20];
char F[20][20], S[20], ch;
int sb[20], eb[20], x, n;
printf("\n Enter no. of Files ::");
scanf("%d",&n);
126
for(i=0;i<n;i++)
{
printf("\n Enter file %d name ::", i+1);
scanf("%s", &F[i]);
printf("\n Enter No. of blocks::", i+1);
scanf("%d",&b[i]);
}
for(i=0;i<n;i++)
{
printf("\n Enter Starting block of file%d::",i+1);
scanf("%d", &sb[i]);
printf("\nEnter blocks for file%d::\n", i+1);
for(j=0; j<b[i]-1;)
{
printf("\n Enter the %dblock ::", j+2);
scanf("%d", &x);
if(b[i] != 0)
{
blocks[i][j] = x;
j++;
}
else
printf("\n Invalid block::");
}
}
printf("\nEnter the Filename :");
scanf("%s", &S);
for(i=0; i<n; i++)
{
if(strcmp(F[i],S) == 0)
{
printf("\nFname\tBsize\tStart\tBlocks\n");
printf("\n--------------------------------------\n");
printf("\n%s\t%d\t%d\t", F[i], b[i], sb[i]);
printf("%d->",sb[i]);
for(j=0; j<b[i]; j++)
127
{
if(b[i] != 0)
printf("%d->", blocks[i][j]);
}
}
}
printf("\n-------------------------------------------\n");
}
OUTPUT
Enter no. of Files ::2
Enter file 1 name ::fcfs
Enter No. of blocks::3
Enter file 2 name ::sjf
Enter No. of blocks::2
Enter Starting block of file1::8
Enter blocks for file1::
Enter the 2block ::3
Enter the 3block ::5
Enter Starting block of file2::2
Enter blocks for file2::
Enter the 2block ::6
Enter the Filename ::fcfs
FnameBsize Start Blocks
---------------------------------------------
fcfs 3 8 8->3->5
---------------------------------------------
RESULT
Thus blocks for file were allocation using linked allocation method.
128
CASE STUDY- ANDROID OS
INTRODUCTION
Android is a mobile operating system based on a modified version of the Linux kernel
and other open-source software, designed primarily for touchscreen mobile devices such as
smartphones and tablets. It is an operating system for low powered devices that run on battery
and are full of hardware like Global Positioning System (GPS) receivers, cameras, light and
orientation sensors, Wi-Fi and LTE (4G telephony) connectivity and a touch screen. Like all
operating systems, Android enables applications to make use of the hardware features through
abstraction and provide a defined environment for applications.
HISTORY
The platform was created by Android Inc. which was bought by Google and released as the
Android Open-Source Project (AOSP) in 2007: Since then, Android has seen numerous updates
which have incrementally improved the operating system, adding new features and fixing bugs
in previous releases. Each major release is named in alphabetical order after a dessert or sugary
treat, with the first few Android versions being called "Cupcake", "Donut", "Eclair", and
"Froyo", in that order. During its announcement of Android KitKat in 2013, Google explained
that "Since these devices make our lives so sweet, each Android version is named after a
dessert". This changed after android pie.
ANDROID ARCHITECTURE:
THE LINUX KERNAL:
The foundation of the Android platform is the Linux kernel. For example, the
Android Runtime (ART) relies on the Linux kernel for underlying functionalities such as
threading and low-level memory management. Using a Linux kernel allows Android to
take advantage of key security features and allows device manufacturers to develop
hardware drivers for a well-known kernel.
HARDWARE ABSTRACTION LAYER (HAL):
The hardware abstraction layer (HAL) provides standard interfaces that expose
device hardware capabilities to the higher-level Java API framework. The HAL consists
of multiple library modules, each of which implements an interface for a specific type of
hardware component, such as the camera or Bluetooth module. When a framework API
makes a call to access device hardware, the Android system loads the library module for
that hardware component.
ANDROID RUNTIME
Each app runs in its own process and with its own instance of the Android
Runtime (ART). ART is written to run multiple virtual machines on low-memory devices
by executing DEX files, a bytecode format designed especially for Android that's
optimized for minimal memory footprint. Build tools, such as d8, compile Java sources
into DEX bytecode, which can run on the Android platform.
129
NATIVE C/C++ LIBRARIES
Many core Android system components and services, such as ART and HAL, are
built from native code that require native libraries written in C and C++. The Android
platform provides Java framework APIs to expose the functionality of some of these
native libraries to apps. For example, you can access OpenGL ES through the Android
framework’s Java OpenGL API to add support for drawing and manipulating 2D and 3D
graphics in your app.
JAVA API FRAMEWORK
The entire feature-set of the Android OS is available to you through APIs written
in the Java language. These APIs form the building blocks you need to create Android
apps by simplifying the reuse of core, modular system components and services, which
include the following:
o A rich and extensible View System you can use to build an app’s UI, including
lists, grids, text boxes, buttons, and even an embeddable web browser.
o A Resource Manager, providing access to non-code resources such as localized
strings, graphics, and layout files.
o A Notification Manager that enables all apps to display custom alerts in the status
bar
o An Activity Manager that manages the lifecycle of apps and provides a common
navigation back stack.
o Content Providers that enable apps to access data from other apps, such as the
Contacts app, or to share their own data
SYSTEM APPS
Android comes with a set of core apps for email, SMS messaging, calendars,
internet browsing, contacts, and more. Apps included with the platform have no special
status among the apps the user chooses to install. So, a third-party app can become the
user's default web browser, SMS messenger, or even the default keyboard (some
exceptions apply, such as the system's Settings app).
CPU SCHEDULING:
The Android operating system uses O (1) scheduling algorithm as it is based on Linux
Kernel 2:6: Therefore, the scheduler is named as Completely Fair Scheduler as the processes can
schedule within a constant amount of time, regardless of how many processes are running on the
operating system.
The process "nice" level impacts the normal "fair" scheduling policy of Linux; threads
that have a higher niceness will be run less often than threads with a lower niceness hus if you
set a thread's priority to Process.THREAD_PRIORITY_BACKGROUND or greater, you will
also be putting the thread into the background cgroup. Set it to
Process.THREAD_PRIORITY_DEFAULT and it will be in the default cgroup.. In the situation
where you have one thread at a "default" priority (as defined in
Process.THREAD_PRIORITY_DEFAULT) will get to run significantly more often than those
at a background priority (or Process.THREAD_PRIORITY_BACKGROUND).
In theory this can make sure that the foreground/UI threads aren't impacted significantly
by background work... however, in practice, it isn't sufficient.
130
To address this, Android also uses Linux cgroups in a simple way to create stricter
foreground vs. background scheduling. The foreground/default cgroup allows thread scheduling
as normal. The background cgroup however applies a limit of only some small percent of the
total CPU time being available to all threads in that cgroup. Android implicitly moves threads
between the default and background cgroups when you use its public APIs to set the thread
priority.
Because of this, by following the normal convention of putting your background worker
threads into the background priority you can ensure that they do not disrupt your foreground UI
thread.
In addition, Android will also move all threads in a process to the background cgroup for
processes that it knows are not critical to the user. Any background process or service process
has its threads put into the background cgroup, regardless of whether individual threads have
requested a foreground scheduling priority.
STORAGE MANAGEMENT:
There are two things that the OS is supposed to do in managing the Internal storage.
First lookout for filled space and others give app access to read/write in internal storage.
In android 10 and above apps can be given only access to media elements of the device. Most
android use e-MMC based storage. They provide up to 300MBps read and write speed. File
system in android is that of a Linux having a root directory, they can be seen in the image on the
right. There are various partitions each having its features. Only internal storage or memory
cards are accessible to the user, rest all are managed by OS itself.
Storage Manager is the interface to the system's storage service. The storage manager
handles storage-related items such as Opaque Binary Blobs (OBBs).
OBBs contain a filesystem that can be encrypted on disk and mounted on-demand from
an application. OBBs are a good way of providing large amounts of binary assets without
packaging them into APKs as they may be multiple gigabytes in size. However, due to their size,
they're most likely stored in a shared storage pool accessible from all programs. The system does
not guarantee the security of the OBB file itself: if any program modifies the OBB, there is no
guarantee that a read from that OBB will produce the expected output.
BATTERY OPTIMIZATION
Battery life is the single most important aspect of the mobile user experience. A device
without power offers no functionality at all. For this reason, it is critically important that apps be
as respectful of battery life as possible.
There are three important things to keep in mind in keeping your app power-thrifty:
131
LAZY FIRST
Making your app Lazy First means looking for ways to reduce and optimize
operations that are particularly battery-intensive. The core questions underpinning Lazy
First design are:
1) Reduce: Are there redundant operations your app can cut out?
2) Defer: Does an app need to perform an action right away?
3) Coalesce: Can work be batched, instead of putting the device into an active
state many times?
PLATFORM FEATURES
Broadly speaking, the Android platform provides two categories of help for you
to optimize your app's battery use. First, it provides several APIs that you can implement
in your app.
There are also internal mechanisms in the platform to help conserve battery life.
While they are not APIs that you implement programmatically, you should still be aware
of them so that your app can leverage them successfully.
Additionally, Android 9 (API level 28) makes a number of improvements to
battery saver mode. Device manufacturers determine the precise restrictions imposed. As
an example, on AOSP builds, the system applies the following restrictions:
1) The system puts apps in app standby mode more aggressively, instead of
waiting for the app to be idle.
2) Background execution limits apply to all apps, regardless of their target API
level.
3) Location services may be disabled when the screen is off.
4) Background apps do not have network access.
As always, it's a good idea to test your app while the battery saver is active. You can turn
on the battery saver manually through the device's Settings > Battery Saver screen.
TOOLING:
You can get even more benefit out of these features by using the tools available for the
platform to discover the parts of your app that consume the most power. Finding what to
target is a big step toward successful optimization.
There are tools for Android, including Profile GPU Rendering and Battery Historian to
help you identify areas that you can optimize for better battery life. Take advantage of
these tools to target areas where you can apply the principles of Lazy First.
132
CASE STUDY – IOS
INTRODUCTION
iPhone operating system(iOS) is a mobile operating system developed by Apple Inc.
used for apple handheld devices. It is used in devices like- iPhone, iPad and iPod. It is the
second most widely used mobile operating system. It supports features like direct manipulation
and can respond to various types of user gestures. It is proprietary and closed source and derived
from macOS. Software development kit (SDK) is provided to create applications. It includes
interfaces for developing, running and testing applications. Apps can be written using system
frameworks and Objective-C programming language.
Initial three versions were introduced with the name iPhone OS. From fourth version,
they renamed it to iOS. With each new version, new features and apps were added. iOS 13 is
latest version which was released in 2019: Its major feature is dark mode and new Map
application with street view capability. It also enhanced its previous apps and features like-Siri,
Heath map and others. iOS 14 is released in 2020.
FEATURES OF IOS
iOS is the operating system for iPhone, iPad and other Apple mobile devices. Based on
Mac OS, the operating system which runs Apple’s line of Mac desktop and laptop computers,
Apple iOS is designed for easy, seamless networking between Apple products. iOS support
extremely good features and some of the common features are:
Multitasking– it allows is released be executed concurrently. This feature allows various
applications toruninbackgroundlike notifications, VoIP, audio, Bluetooth access, app
updates and may more.
SpringBoard – It is used for managing home screen.
Gesture recognition
Wifi, Bluetooth and support for VPN
Access to Apple App store
Safari browser
Front and read camera with videos capturing facility
Siri – it is an intelligent personal assistant feature which can take voice queries and can
take and recommendations, used for setting reminders etc.
Game center – it is multiplayer gaming network available online.
Compatible with iCloud – iCloud is cloud service provided by Apple.
Push email service – Apple’s email server allows mails to be delivered as they arrive.
Accelerometer, gyroscope, and magnetometer – these are sensor interfaces used to listen
various events.
Apple pay – it is payment technology which can store credit card details to pay for
services.
Services like Maps, contacts, web pages, messages, location
Various security features – face ID, pass code, 2 factor authentication.
Home Pod – it can identify family members by voice and can handoff calls, music etc on
other devices.
133
HomeKit – it is home automation controlling system.
CarPlay – this allows interacting with iOS during drive. Also allows access tom phone
apps
EVOLUTION OF OS
iOS was first introduced with iPhone in Jan 2007 and released in June 2007: At first
introduction Steve Jobs claimed it to be running OS X and running desktop class application but
during release introduced it with the name “iPhone OS”. Initially, there was no support for third
party applications. In March 2008, Apple announced software development kit for iPhone. In
July 2008, iOS app store opened with 500 applications which increased to 3000 in Sept 2008 and
after successive growth through the years increased to 2:2 million in 2017: It is also estimated to
reach 5 million by 2020. iOS has seen a lot of changes since its inception. Following are the
important milestones in iOS:
iOS was first introduced with iPhone in Jan 2007 and released in June 2007:
Apple’s iOS first SDK was released on March 6, 2008:
The initial release was named iPhone OS which was later changed to iOS on June 7,
2010:
iPhone OS 1 was released on March 6, 2008, and is the first version of the popular
operating system. The support for iPhone OS 1 ended after two years, i.e., 2010:
iPhone OS 2, as the name suggest, is the 2nd big release for the iOS. The release was
done in conjunction with iPhone 3G, and anyone with the previous version can easily
upgrade to the latest version. Also, this version introduced the App store, which becomes
the hub for installing new apps. New SDK was also released for developers with support
ending in 2011:
The third big release was Apple iOS 3: It came into existence in June 2009 with support
ending in late 2012: New features such as copy, paste, etc. are added to the OS.
iOS 5 was released on June 6, 2001: It brought support for iPad Touch (3rd generation)
and iPad (1st generation).
iOS 6 went live on September 19, 2012, for the 4thgenerationApple devices.
iOS 7 was released for public on September 18, 2013: It supported two new phones by
Apple, the Apple iPhone 5S and iPhone 5C.
Just like the old release, iOS 8 released for public on September 9, 2014, with support for
their best phone devices, the iPhone 6 and iPhone 6 Plus. They dropped support for older
devices.
iOS 9 was made public on September 16, 2015: Apple changed how they support legacy
hardware and iOS 9 became the first Apple OS that supported 22 devices.
iOS 10 was announced on June 13, 2016 at WWDC (Worldwide Developers Conference
event and was released to public in September, 2016 along with iPhone 7 and iPhone 7
plus.
iOS 11 was made public on September, 2017 along with iPhone 8 and iPhone 8 Plus. It
has dropped 32-bit applications making iOS 11 as a 64-bit OS that only runs 64- bit apps.
iOS 12 was made public on September 2018 along with iPhone XS, iPhone XS Max,
iPhone XR.
134
Apple announced iOS 13 and made public on September, 2019: The principal features
include Dark Mode and Emoji support. The NFC (Near Field Communication)
framework supports reading several types of contactless smartcards and tags.
Apple released iOS 14 and iPadOS 14 on 9th July 2020. All devices that support iOS 13
also support iOS 14: Some new features include widgets that be now be placed directly
on the home-screen, along with theApp library which automatically categorizes apps into
one page, Picture in Picture, Car- key technology to unlock and start a car with NFC. It
also allows the user to have incoming calls shown in banners rather than taking up the
whole screen.
ARCHITECTURE OF IOS
iOS architecture is written in Objective-C language and comprised of four layers (layered
architecture). It consists of a stack of four layers – Core OS, Core services, media layer, and
Cocoa Touch as shown in Figure 1:
Apps installed on system communicate with the iOS which in turn communicates with
the hardware. Bottom level layers in the iOS stack are responsible for basic services while the
upper layers are responsible for providing interface and graphics designing.
Apple provides system interfaces called Frameworks which is a package that stores 314 dynamic
shared libraries. It contains various resources like – header files, supported apps, images. Each
layer of iOS contains different set of frameworks that can be used to developers to design apps.
135
All threads of a single process have same access rights and also shares same address
space (virtual memory). They can also communicate with each other and other processes. Every
thread has its own stack of execution and scheduled for execution by kernel separately. IOS has
the capability to execute multiple programs parallel but most of the execution is done in
background and does not require continuous processing. The application that runs in foreground
keeps the processor and other resources busy.
THREADING PACKAGES
Applications may require creation of threads. IOS supports thread management
and synchronization along with other new technologies. The technologies used to
manage thread in iOS can be POSIX threads or Cocoa threads.
POSIX threads are based on C language. This must be used when application
needs to be designed for multiple platforms. Here threads are managed using pthread
library. Communication between threads can be done using ports, shared memory or
conditions. For Cocoa applications, threads are created using NSThread class. It allows
detached thread to be created. Detached thread is the one in which system automatically
reclaims thread’s resources when it terminates.
THREADS ALTERNATIVES
Threadsarelowleveldoingconcurrencyandmanagingsynchronizationbecomesdiffic
ult for application development. Also, the use of thread adds processor and memory
overheads. iOS henceoffersalternativesto thread programming. Executionofconcurrent
tasks or processes on iOS is managed by asynchronous designing approach like
traditional thread approach. Applications should only define specific tasks instead of
creating threads as threads are low level and should leave it to system. Threads when
managed by system, gives scalability to applications. The various techniques provided by
iOS to manage tasks asynchronously are:
o GRAND CENTRAL DISPATCH (GCD)
In this approach user only defines the task to be done and add it to the
appropriate dispatch queue. GCD then creates threads as needed and schedules
them. Since in this approach thread management and execution is done by
system, it is more efficient than traditional threads approach.
o OPERATION QUEUES
They are similar to dispatch queue and are object-C objects. User defines
the task to execute and add it to operation queue. Scheduling and execution are
then done by operation queue.
o DISPATCH QUEUES
Dispatch queue are used for execution of customized tasks. It executes the
task serially or concurrently in first-in first-out order. Serial dispatcher waits for
the task to complete before de-queuing, whereas concurrent dispatcher does not
wait for the tasks to nish before starting new tasks.
o Operation Queues:
In operation queues the order of execution of task is dependent upon
many factors. One such factor is the dependence of one task on the completion of
another task. User when defining a task should also configure dependency.
136
The various advantages of using dispatch and operation queues in place of
threads offer various advantages:
1) No need to store thread stack hence reduces memory requirements
2) User need not to configure and manage threads.
3) User need not to schedule threads.
4) It is easy to write code as compared to threads.
iCloud CONTAINER
iCloud service allows user to store their documents, photos, files, etc. to be stored in
cloud. Users when require can download these from their devices or share with other users. iOS
allows users data be automatically backed up in cloud through this service. This feature is
available in iOS 7 onwards. iCloud container is used to store files for apps that use iCloud. Files
and folders can be created by apps in the same way as local file folders are created. Files and
their attributes are copied to iCloud. Primary iCloud container ofapps stores native files. Within
each container two subdirectories – documents and data are present. Files present within
document subdirectory are visible to user as separate document which can be individually
deleted. Whereas files not within document subdirectory is displayed as single entity in iCloud
user interface called data.
ii) BSD
In BSD instead of giving access writes to individual users, it allows access
to be given on the basis of class of users. There exist three classes of users –
owner of data or file, group of users, all other users.
iii) ENCRYPTION
iOS allows files on disk to be encrypted. Files that are needed to be
encrypted can be designated by apps. When a device containing encrypted data is
unlocked by user, a decryption key is generated by system to enable access to
file. Whereas, when user locks the device, to prevent unauthorized access, the
decryption key is destroyed by the system.
138
CASE STUDY – VMWARE WORKSTATION
INTRODUCTION
VMware Workstation includes Type 2 hypervisors. Unlike a Type 1 hypervisor, which
replaces the underlying OS altogether, a Type 2 hypervisor runs as an application on the desktop
OS and lets desktop users run a second OS atop their main (host) OS.
VMware Workstation comes in two flavors:
Workstation Player is a free version that supports a single guest OS.
Workstation Pro supports multiple guest operating systems and integrates with
VMware's enterprise virtualization management tools.
139
VIRTUAL DESKTOP INTEGRATION
VMware offers a third model that sits somewhere between the server and desktop
virtualization above—virtual desktop integration (VDI). VDI virtualizes desktop operating
systems on a server.
VDI offers centralized desktop management, letting you configure and troubleshoot
desktop operating systems without remote access or on-site visits. Users can access their
applications and data from any device, anywhere, without the need to invest in expensive, high-
powered client endpoint equipment. Sensitive data secure never leaves the server.
VMware Horizon
VMware Horizon is VMware's suite of VDI tools. It supports both Windows and Linux
desktops. You can run your virtual desktops on your own premises or use Horizon Cloud to run
them in multiple hosted cloud environments.
The Horizon suite includes Horizon Apps, a platform that lets you create your own
custom app store for enterprise users to run on their virtual desktops. Your users can access a
mixture of on-premise, SaaS, and mobile applications using a single set of login credentials.
Explore the benefits of virtual desktop integration with VMware Horizon on IBM
Cloud.
vSphere
VMware vSphere (link resides outside IBM) is VMware’s enterprise virtualization
platform, including both the ESXi hypervisor software and the vCenter Server management
platform for managing multiple hypervisors.
vSphere is available in three configurations: Standard, Enterprise Class, and Platinum.
Each support policy-driven virtual machine storage, live workload migration, and built-in
cybersecurity features. The higher-end options include VM-level encryption, integrated
container management, load-balancing, and centralized network management. Platinum alone
supports automated responses to security threats and integration with third-party security
operations tools.
vCenter
One of vSphere’s important components is vCenter Server (link resides outside IBM).
This is the management component of vSphere. It allows you to manage virtual machine
deployments across a large collection of host servers. It assigns virtual machines to hosts,
allocates resources for them, monitors performance, and automates workflow. This tool can be
used to manage user privileges based on a user’s own policies.
VCenter Server has three main components:
vSphere Web Client is the platform's user-interface, providing administrators with
browser-based access to all functions
VCenter Server Database is the data repository for the product. It stores data necessary
for server hosts to run hypervisors and virtual machines.
140
VCenter Single Sign-On lets you access the entire vSphere infrastructure with a single
login.
CLUSTERING:
Using a hypervisor on a host server will maximize your use of that hardware, but most
enterprises users will need more VMs than they can fit on a single physical server. That’s where
VMWare’s clustering technology comes in.
VMware shares resources between hosts by grouping them into a cluster and treating
them as a single machine. You can then use VMware’s clustering technology to pool hardware
resources between the hypervisors running on each host in the cluster. When adding a VM to a
cluster, you can give it access to these pooled resources. There may be many clusters in a
VMware-powered enterprise.
VMware allows you to create and manage clusters within its vSphere environment. A
cluster supports many vSphere features, including workload balancing, high availability, and
fault-tolerant resilience.
VMware clustering gives you access to several VMware functions to make your virtual
infrastructure run smoothly and reliably:
VMware HA
VMware’s vSphere High Availability (HA) (link resides outside IBM) solution lets you
switch virtual machines between physical hosts if the underlying hardware fails. It monitors the
cluster and if it detects a hardware failure, it restarts its VMs on alternate hosts.
vSphere HA designates one host in a cluster as the “master,” the others are called
“slaves.” The master communicates with vCenter Server, reporting back on the state of protected
VMs and slave hosts.
VMware Fault Tolerance
While vSphere HA provides rapid recovery from outages, you can still expect downtime while it
moves and restarts a VM. If you need more protection for mission-critical applications, vSphere
Full Tolerance (link resides outside IBM) offers a higher level of availability. It promises no loss
of data, transactions, or connections.
vSphere Fault Tolerance works by running a primary and secondary VM on separate hosts in the
cluster and ensuring that they are identical at any point. If either of their hosts fails, the
remaining host continues operating and vSphere Fault Tolerance creates a new secondary VM,
reestablishing redundancy. vSphere automates the whole process.
VMware DRS
If you allow many VMs to run unmanaged across your host machines, you will get into trouble.
Some VMs will be more demanding on CPU and memory resources than others. This can create
unbalanced workloads, with hosts handling more than their share of work while others sit idle.
VMware Distributed Resource Scheduling (DRS) (link resides outside IBM) solves that problem
by balancing workloads between different ESXi hypervisors.
DRS, a feature of vSphere Enterprise Plus, works within a cluster of ESXi hosts that are sharing
resources. It monitors host CPU and RAM usage and moves the VMs between them to avoid
overworked and underused hosts. You can set these allocation policies yourself to reallocate
resources aggressively or to rebalance less often.
141
VIRTUALIZING THE REST OF THE DATA CENTER
VMware made a name for itself virtualizing servers and then desktop operating systems. In
2012, it announced plans to virtualize and automate everything in the data center in a concept
called the software-defined data center (SDDC).
VMWARE CONTAINERS
Developers increasingly use containers as an alternative to VMs. Like VMs, they are virtual
environments containing applications abstracted from the physical hardware. However,
containers share the underlying host OS kernel instead of virtualizing an entire OS as VMs do.
Containers offer more agility and use physical computing power more efficiently than VMs, but
they are not suitable for all cases. You might want to develop an entirely new application that
divides small pieces of functionality called microservices into separate containers, making
application development and maintenance more agile. On the other hand, a legacy application
written to run as a single binary program might be more suitable running in a VM that mirrors
the environment it is used to. You can take advantage of containers and VMs together using the
VMware’s vSphere Integrated Containers (link resides outside IBM) feature, which bridges the
gap between the two by allowing containers to run in VMware environments. It comprises three
components:
vSphere Integrated Container Engine lets developers run containerized apps based on
the popular Docker container format alongside VMs on the same vSphere infrastructure.
Project Harbor is an enterprise container registry that lets developers store and
distribute container images so that other developers can reuse them.
Project Admiral is a management portal that lets development teams provision and
manage containers.
AIRWATCH
AirWatch (link resides outside IBM) is a VMware division focusing on enterprise mobility
management. Its technology is the basis for VMware’s Workspace ONE Unified Endpoint
143
Management product, which lets you manage endpoints ranging from desktops through to small-
footprint Internet of Things (IoT) devices using a single management console.
Endpoints are security vulnerabilities for companies. Attackers can gain access to the whole
network by infecting a single endpoint with malware. Endpoints are also vulnerable to physical
theft, making the data on them vulnerable. Managing all endpoints centrally, even when they are
not on the office network, helps administrators ensure that the endpoints are properly secured
and encrypted.
The endpoint management product supports a range of operating systems, from Android through
to MacOS and even IoT-focused systems such as QNX. You can configure usage policies and
security settings for each device on the network.
144