Sei sulla pagina 1di 91

SRINIVASAN ENGINEERING COLLEGE PERAMBALUR-621212 DEPARTMENT OF INFORMATION TECHNOLOGY CS2257 OPERATING SYSTEMS LABORATORY II - IT (2011-2015)

PREPARED BY Mr. G.Baskaran M.E., Assistant professor/Information Technology, Srinivasan Engineering college, Perambalur-621212 Anna university, Chennai (R-2008) Academic year (2012-13) IV SEMESTER 1

DEDICATED TO
My Family & My Friends

PREFACE
Operating Systems Laboratory Manual is intended as an introduction of executing programs for reader and students. This manual provides a handy guide to the developers in managing computer hardware. The purpose of an operating system is to provide an environment in which a user can execute programs in a convenient and efficient manner.

ACKNOWLEDGEMENT
Behind every achievement lies an unfathomable sea of gratitude to all those who made the achievement possible without whom it would never have come into existence. I give all glory and thanks to our god almighty for showering upon, the necessary wisdom and grace for accomplishing the lab manual. I am indebted to our honorable chairman and founder of Dhanalakshmi Srinivasan Group of institutions, SHRI.A.SRINIVASAN, for his kind encouragement. I am very much happy to thank our beloved Principal Dr.B.KARTHIKEYAN M.E., Ph.D., for his unflinching devotion and continuous encouragement motivated me to complete this lab manual. I extend my warm gratitude to our Head of the Department, Mr. S.SATHISHKUMAR ME., for his valuable suggestion and kind guidance throughout the manual preparation. Finally, I thank my parents, and my friends without whom this course would have been a dream.

CS2257 OPERATING SYSTEMS LABORATORY (Common to CSE and IT)

(Implement the following on LINUX or other Unix like platform. Use C for high level language implementation) LIST OF EXPERIMENTS

1.

Write programs using the following system calls of UNIX operating system: fork, exec, getpid, exit, wait, close, stat, opendir, readdir

2. 3. 4.

Write programs using the I/O system calls of UNIX operating system (open, read, write, etc) Write C programs to simulate UNIX commands like ls, grep, etc. Given the list of processes, their CPU burst times and arrival times, display/print the Gantt chart for FCFS and SJF. For each of the scheduling policies, compute and print the average waiting time and average turnaround time. (2 sessions)

5.

Given the list of processes, their CPU burst times and arrival times, display/print the Gantt chart for Priority and Round robin. For each of the scheduling policies, compute and print the average waiting time and average turnaround time. (2 sessions)

6.

Developing Application using Inter Process Communication (using shared memory, or message queues)

7. 8. 9. 10.

Implement the Producer Consumer problem using semaphores (using UNIX system calls). Implement some memory management schemes I Implement some memory management schemes II Implement any file allocation technique (Linked, Indexed or Contiguous)

Total: 45

Example for exercises 8 and 9: Free space is maintained as a linked list of nodes with each node having the starting byte address and the ending byte address of a free block. Each memory request consists of the process-id and the amount of storage space required in bytes. Allocated memory space is again maintained as a linked list of nodes with each node having the process-id, starting byte address and the ending byte address of the allocated space. When a process finishes (taken as input) the appropriate node from the allocated list should be deleted and this free disk space should be added to the free space list. [Care should be taken to merge contiguous free blocks into one single block. This results in deleting more than one node from the free space list and changing the start and end address in the appropriate node]. For allocation use first fit, worst fit and best fit.

CONTENTS

S.NO

LIST OF EXPERIMENTS

PAGE NO

1 2 3 4a 4b 5a 5b 6a 6b 7 8 9 10

Implementation of System Calls Implementation of I/O System Calls Simulation of UNIX Commands Implementation of FCFS Scheduling Implementation of SJF Scheduling Implementation of Priority Scheduling Implementation of Round Robin Scheduling Inter Process Communication Using Shared Memory Inter Process Communication Using Message Queues Producer Consumer Problem Using Semaphores Memory Management Schemes I Memory Management Schemes II File Allocation Technique (Linked, Indexed Or Contiguous)

7 18 23 28 33 38 42 47 50 55 59 67 74

STUDY OF LINUX INTRODUCTION TO LINUX

Linux is a generic term referring to Unix-like computer operating systems based on the Linux kernel. Their development is one of the most prominent examples of free and open source software collaboration; typically all the underlying source code can be used, freely modified, and redistributed by anyone. The name "Linux" comes from the Linux kernel, originally written in 1991 by Linus Torvalds. The rest of the system usually comprises components such as the Apache HTTP Server, the X Window System, the K Desktop Environment, and utilities and libraries from the GNU operating system (announced in 1983 by Richard Stallman). Many quantitative studies of free / open source software focus on topics including market share and reliability, with numerous studies specifically examining Linux. The Linux market is growing rapidly, and the revenue of servers, desktops, and packaged software running Linux was expected to exceed $35.7 billion by 2008. LINUX FILE SYSTEM A file system is the methods and data structures that an operating system uses to keep track of files on a disk or partition; that is, the way the files are organized on the disk. The word is also used to refer to a partition or disk that is used to store the files or the type of the file system. The difference between a disk or partition and the file system it contains is important. A few programs (including, reasonably enough, programs that create file systems) operate directly on the raw sectors of a disk or partition; if there is an existing file system there it will be destroyed or seriously corrupted. Most programs operate on a file system, and therefore won't work on a partition that doesn't contain one (or that contains one of the wrong type). Before a partition or disk can be used as a file system, it needs to be initialized, and the bookkeeping data structures need to be written to the disk. This process is called making a file system. Most UNIX file system types have a similar general structure, although the exact details vary quite a bit. The central concepts are superblock, inode, data block, directory block, and indirection block. The superblock contains information about the file system as a whole, such as its size (the exact information here depends on the file system). An inode contains all information about a file, except its name. The name is stored in the directory, together with the number of the inode. A directory entry consists of a filename and the number of the inode which represents the file. The 8

inode contains the numbers of several data blocks, which are used to store the data in the file. There is space only for a few data block numbers in the inode, however, and if more are needed, more space for pointers to the data blocks is allocated dynamically. These dynamically allocated blocks are indirect blocks; the name indicates that in order to find the data block, one has to find its number in the indirect block first. Like UNIX, Linux chooses to have a single hierarchical directory structure. Everything starts from the root directory, represented by /, and then expands into sub-directories instead of having socalled 'drives'. In the Windows environment, one may put one's files almost anywhere: on C drive, D drive, E drive etc. Such a file system is called a hierarchical structure and is managed by the programs themselves (program directories), not by the operating system. On the other hand, Linux sorts directories descending from the root directory / according to their importance to the boot process. Linux, like Unix also chooses to be case sensitive. What this means is that the case, whether in capitals or not, of the characters becomes very important. This feature accounts for a fairly large proportion of problems for new users especially during file transfer operations whether it may be via removable disk media such as floppy disk or over the wire by way of FTP. The image below shows the file system of Linux

The following bin/ dev/ home/ lost+found/ proc/ sbin/ usr/ boot/ etc/ lib/ mnt/ root/ tmp/ var/ are explained in detail. /sbin - This directory contains all the binaries that are essential to the working of the system. These include system administration as well as maintenance and hardware configuration programs. /bin - In contrast to /sbin, the bin directory contains several useful commands that are used by both the system administrator as well as non privileged users. /boot - This directory contains the system.map file as well as the Linux kernel. Lilo places the boot sector backups in this directory.

10

/dev - This is a very interesting directory that highlights one important characteristic of the Linux file system - everything is a file or a directory. Look through this directory and you should see hda1, hda2 etc, which represent the various partitions on the first master drive of the system. /dev/cdrom and /dev/fd0 represent your CDROM drive and your floppy drive. /etc - This directory contains all the configuration files for your system. Your lilo.conf file lies in this directory as does hosts, resolv.conf and fstab. /home These are the user home directories, which can be found under /home/username. /lib - This contains all the shared libraries that are required by system programs. Windows equivalent to a shared library would be a DLL file. /lost+found - Linux should always go through a proper shutdown. Sometimes your system might crash or a power failure might take the machine down. Either way, at the next boot, a lengthy filesystem check using fsck will be done. Fsck will go through the system and try to recover any corrupt files that it finds. The result of this recovery operation will be placed in this directory. /mnt - This directory usually contains mount points or sub-directories where you mount your floppy and your CD. /opt - This directory contains all the software and add-on packages that are not part of the default installation. /proc - This is a special directory on your system. /root - We talked about user home directories earlier and well this one is the home directory of the user root. /tmp - This directory contains mostly files that are required temporarily. /usr - This is one of the most important directories in the system as it contains all the user binaries. /usr/src/linux contains the source code for the Linux kernel. /var - This directory contains spooling data like mail and also the output from the printer daemon. The above content briefs about Linux and the file system of Linux. Thus the Linux file system is explained in detail.

11

Uses of Linux Linux is a widely ported operating system kernel. The Linux kernel runs on a highly diverse range of computer architectures: in the hand-held ARM-based iPAQ and the mainframe IBM System z9, System z10; in devices ranging from mobile phones to supercomputers.[68] Specialized distributions exist for less mainstream architectures. The ELKS kernel fork can run on Intel 8086 or Intel 80286 16-bit microprocessors, while the Clinux kernel fork may run on systems without a memory management unit. The kernel also runs on architectures that were only ever intended to use a manufacturer-created operating system, such as Macintosh computers (with both PowerPC and Intel processors), PDAs, video game consoles, portable music players, and mobile phones. See List of Linux supported architectures.

Applications of Linux 1. 2. 3. 4. 5. OpenShot (Video editor) Apache (Web server) Firefox (Web browser) Dropbox (Online storage) Asterisk (Telephony)

Linux Advantages 1. Low cost: You dont need to spend time and money to obtain licenses since Linux and much of its software come with the GNU General Public License. You can start to work immediately without worrying that your software may stop working anytime because the free trial version expire.s 2. Stability: Linux doesnt need to be rebooted periodically to maintain performance levels. It doesnt freeze up or slow down over time due to memory leaks and such. Continuous uptimes of hundreds of days (up to a year or more) are not uncommon. 3. Performance: Linux provides persistent high performance on workstations and on networks. It can handle unusually large numbers of users simultaneously, and can make old computers sufficiently responsive to be useful again. 4. Network friendliness: Linux was developed by a group of programmers over the Internet and has therefore strong support for network functionality; client and server systems can be easily 12

set up on any computer running Linux. It can perform tasks such as network backups faster and more reliably than alternative systems. 5. Fast and easy installation: Most Linux distributions come with user-friendly installation and setup programs. Popular Linux distributions come with tools that make installation of additional software very user friendly as well. 6. Full use of hard disk: Linux continues work well even when the hard disk is almost full. 7. Multitasking: Linux is designed to do many things at the same time; e.g., a large printing job in the background wont slow down your other work. 8. Security: Linux is one of the most secure operating systems. Walls and flexible file access permission systems prevent access by unwanted visitors or viruses. Linux users have to option to select and safely download software, free of charge, from online repositories containing thousands of high quality packages. No purchase transactions requiring credit card numbers or other sensitive personal information are necessary. 9. Open Source: If you develop software that requires knowledge or modification of the operating system code, Linuxs source code is at your fingertips. Most Linux applications are Open Source as well. Disadvantages of Linux:
1.

Understanding Becoming familiar with the Linux operating system requires patience as well as a strong learning curve. You must have the desire to read and figure things out on your own, rather than having everything done for you. Check out the 20 must read howtos and guides for Linux.

2.

Compatibility Because of its free nature, Linux is sometimes behind the curve when it comes to brand new hardware compatibility. Though the kernel contributors and maintainers work hard at keeping the kernel up to date, Linux does not have as much of a corporate backing as alternative operating systems. Sometimes you can find third party applications, sometimes you cant.

3.

Alternative Programs Though Linux developers have done a great job at creating alternatives to popular Windows applications, there are still some applications that exist on Windows that have no equivalent Linux application. Read Alternatives to Windows Applications to find out some of the popular alternatives. 13

Ex.No: 1 IMPLEMENTATION OF SYSTEM CALLS

Aim:

To write a program using process system call.

Algorithm:

NAME fork create a new process system call. SYNOPSIS #include<unistd.h> pid_t fork(void); DESCRIPTION The fork() function shall create a new process. The new process (child process) shall be an exact copy of the calling process (parent process). The child process shall have a unique process ID. System call fork() is used to create processes. It takes no arguments and returns a process ID. The purpose of fork() is to create a new process, which becomes the child process of the caller. After a new child process is created, both processes will execute the next instruction following the fork() system call. Therefore, we have to distinguish the parent from the child. This can be done by testing the returned value of fork(): If fork() returns a negative value, the creation of a child process was unsuccessful. fork() returns a zero to the newly created child process. fork() returns a positive value, the process ID of the child process, to the parent. EXECUTION Parent and children execute concurrently Parent waits until children terminate

14

NAME execl, -execute a file SYNOPIS #include<unistd.h> extern char **environ; int execl(const char *path, const char *arg(), /*, (char *)0 */); DESCRIPTION The exec family of functions shall replace the current process image with a new process image. The new image shall be constructed from regular, executable file called the new process image file. There shall be no return from a successful exec, because the calling process image is overlaid by the new process image. Fork-exec is a commonly used technique in Unix whereby an executing process spawns a new program. fork() is the name of the system call that the parent process uses to "divide" itself ("fork") into two identical processes. After calling fork(), the created child process is actually an exact copy of the parent - which would probably be of limited use - so it replaces itself with another process using the system call exec(). The parent process can either continue execution or wait for the child process to complete. The child, after discovering that it is the child, replaces itself completely with another program, so that the code and address space of the original program are lost. If the parent chooses to wait for the child to die, then the parent will receive the exit code of the program that the child executed. Otherwise, the parent can ignore the child process and continue executing as it normally would; to prevent the child becoming a zombie it should wait on children at intervals or on SIGCHLD. When the child process calls exec(), all data in the original program is lost, and replaced with a running copy of the new program. This is known as overlaying. Although all data is replaced, the file descriptors that were open in the parent are closed only if the program has explicitly marked

15

them close-on-exec. This allows for the common practice of the parent creating a pipe prior to calling fork() and using it to communicate with the executed program. Using execl() The following example executes the ls command, specifying the pathname of the executable (/bin/ls) and using arguments supplied directly to the command to produce single-column output. #include<unistd.h> int ret; ret=execl(/bin/ls, ls, -l, (char *)0);

NAME exit, _exit terminate a process SYNOPIS #include<stdlib.h> void exit(int status); DESCRIPTION The exit status will be n, if specified. Otherwise, the value will be the exit value of the last command executed, or zero if no command was executed. When exit is executed in a trap action, the last command is considered to be the command that executed immediately preceding the trap action. This system call is used to terminate (normal/abnormal) the current running program.

NAME wait wait for a child process to stop or terminate SYNOPIS #include<sys/types.h> #include<sys/wait.h> pid_t wait(int *stat_loc); DESRIPTION The wait() and waitpid() functions allow the calling process to obtain status information pertaining to one of its child processes. Various options permit status information to be obtained for child 16

processes that have terminated or stopped. If status information is available for two or more child processes, the order in which their status is reported is unspecified. There are a number of system calls that a process can use to obtain file information. The most useful one is "stat" system call. The stat() system call is used to obtain file information. _ A parent process usually needs to synchronize its actions by waiting until the child process has either stopped or terminated its actions. _ The wait() system call allows the parent process to suspend its activities until one of these actions has occurred. _ The wait() system call accepts a single argument, which is a pointer to an integer and returns a value defined as type pid_t. _ If the calling process does not have any child associated with it, wait will return immediately with a value of -1. _ If any child processes are still active, the calling process will suspend its activity until a child process terminates.

NAME Readdir() To read a directory SYNOPSIS #include <sys/types.h> #include <dirent.h> struct dirent *readdir(DIR *dir); DESCRIPTION The readdir() function returns a pointer to a dirent structure representing the next directory entry in the directory stream pointed to by dir. It returns NULL on reaching the end-of-file or if an error occurred. On Linux, the dirent structure is defined as follows: struct dirent { ino_t d_ino; /* inode number */ off_t d_off; /* offset to the next dirent */ unsigned short d_reclen; /* length of this record */ unsigned char d_type; /* type of file */ char d_name[256]; /* filename */ 17

}; The data returned by readdir() may be overwritten by subsequent calls to readdir() for the same directory stream. RETURN VALUE The readdir() function returns a pointer to a dirent structure, or NULL if an error occurs or end-of-file is reached. On error, errno is set appropriately.

NAME Opendir() To open a directory SYNOPSIS #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name); DESCRIPTION The opendir() function opens a directory stream corresponding to the directory name, and returns a pointer to the directory stream. The stream is positioned at the first entry in the directory. RETURN VALUE The opendir() function returns a pointer to the directory stream. On error, NULL is returned, and errno is set appropriately.

18

Program: a) fork, execl, getpid, exit, wait

#include<stdio.h> #include<sys/types.h> void main() { pid_t pid; int i; pid=getpid(); printf("\nbefore fork %d",pid); pid=fork(); if(pid==0) printf("/n nth this line from child \n thechild processid %d value=%d",getpid(),i); else if(pid==1) printf("\nthis line is from parent value=%d",i); else if(pid<1) { printf("\n fork failed"); exit(1); } if(pid==0) { execl("/bin/ls", "ls" ,"-1",(char*)0); } if(pid > 0) wait((int *)0); }

19

OUTPUT:

[cs2002@localhost ~]$ cc psc.c [cs2002@localhost ~]$ ./a.out

before fork 3749/n nth this line from child a.out data elamugil hai.c isc.c kumar l4.c

20

b) stat

#include<stdio.h> #include<sys/stat.h> main() { int fd; char pathl[10]; struct stat*nfile; nfile=(struct stat*)malloc(sizeof(struct stat)); printf("\n Enter the file name:\t"); scanf("%s",pathl); stat(pathl,nfile); printf("Program inodeno:%d\n",nfile->st_ino); printf("Program Size :%d\n",nfile->st_blksize); printf("Access Time :%s\n",ctime(&nfile->st_atime)); printf("Modified Time :%s\n",ctime(&nfile->st_mtime)); printf("Protection printf("User id printf("Group id :%d\n",nfile->st_mode); :%d\n",nfile->st_uid); :%d\n",nfile->st_gid);

printf("Device driverno:%d\n",nfile->st_dev); printf("No. of links :%d\n",nfile->st_nlink); return 0; }

21

OUTPUT:

[cse04@LINUXSERVER aravind]$ cc status.c [cse04@LINUXSERVER aravind]$ ./a.out Enter the file name: sum.sh

Program inodeno:1815607 Program Size :4096 Access Time :Thu Mar 30 11:45:06 2006

Modified Time :Tue Mar 7 10:31:36 2006 Protection User id Group id :33204 :514 :514

Device driverno:769 No. of links :1

22

c) opendir & readdir

//ls command implementation using opendir & readdir //ls command implementation

#include<stdio.h> #include<dirent.h> main(int argc,char *argv[]) { DIR * dir; struct dirent *direntry; dir=opendir(argv[1]); while((direntry=readdir(dir))!=NULL) printf("%d %s\n",direntry->d_ino,direntry->d_name); closedir(dir); }

23

OUTPUT:

[cse04@LINUXSERVER vaishu]$ cc ordir.c [cse04@LINUXSERVER vaishu]$ ./a.out uma 1750301 . 3270767 .. 1750302 aaa

Result:

Thus the process system call program was executed. 24

Ex.No: 2 IMPLEMENTATION OF I/O SYSTEM CALL

Aim:

To write a program for I/O system calls.

DESCRIPTION File-I/O through system calls is simpler and operates at a lower level than making calls to the C fileI/O library. There are seven fundamental file-I/O system calls: creat() Create a file for reading or writing. open() Open a file for reading or writing. close() Close a file after reading or writing.. write() Write bytes to file. read() Read bytes from file. These calls were devised for the UNIX operating system and are not part of the ANSI C spec. Use of these system calls requires a header file named "fcntl.h": The creat() Sytem Call The "creat()" system call, of course, creates a file. It has the syntax: int fp; /* fp is the file descriptor variable */

fp = creat( <filename>, <protection bits> ); Ex: fp=creat(students.dat,RD_WR); This system call returns an integer, called a "file descriptor", which is a number that identifies the file generated by "creat()". This number is used by other system calls in the program to access the file. Should the "creat()" call encounter an error, it will return a file descriptor value of -1. The "filename" parameter gives the desired filename for the new file. The "permission bits" give the "access rights" to the file. A file has three "permissions" associated with it: 1. Write permission - Allows data to be written to the file. 2. Read permission - Allows data to be read from the file. 3. Execute permission - Designates that the file is a program that can be run. 25

These permissions can be set for three different levels: User level: Permissions apply to individual user. Group level: Permissions apply to members of user's defined "group". System level: Permissions apply to everyone on the system. The open() Sytem Call The "open()" system call opens an existing file for reading or writing. It has the syntax: <file descriptor variable> = open( <filename>, <access mode> ); The "open()" call is similar to the "creat()" call in that it returns a file descriptor for the given file, and returns a file descriptor of -1 if it encounters an error. However, the second parameter is an "access mode", not a permission code. There are three modes (defined in the "fcntl.h" header file): O_RDONLY Open for reading only. O_WRONLY Open for writing only. O_RDWR Open for reading and writing. For example, to open "data" for writing, assuming that the file had been created by another program, the following statements would be used: int fd; fd = open( "students.dat", O_WRONLY ); A few additional comments before proceeding: A "creat()" call implies an "open()". There is no need to "creat()" a file and then "open()" it. The close() Sytem Call The "close()" system call is very simple. All it does is "close()" an open file when there is no further need to access it. The "close()" system call has the syntax: close( <file descriptor> ); The "close()" call returns a value of 0 if it succeeds, and returns -1 if it encounters an error. The write() Sytem Call The "write()" system call writes data to an open file. It has the syntax: write( <file descriptor>, <buffer>, <buffer length> );

26

The file descriptor is returned by a "creat()" or "open()" system call. The "buffer" is a pointer to a variable or an array that contains the data; and the "buffer length" gives the number of bytes to be written into the file. While different data types may have different byte lengths on different systems, the "sizeof()" statement can be used to provide the proper buffer length in bytes. A "write()" call could be specified as follows: float array[10]; write( fd, array, sizeof( array ) ); The "write()" function returns the number of bytes it actually writes. It will return -1 on an error. The read() Sytem Call The "read()" system call reads data from a open file. Its syntax is exactly the same as that of the "write()" call: read( <file descriptor>, <buffer>, <buffer length> ); The "read()" function returns the number of bytes it actually returns. At the end of file it returns 0, or returns -1 on error.

Algorithm:

1. Start the Program. 2. Open a file for O_RDWR for read and write, O_CREATE for creating a file, O_TRUNC for truncates a file. 3. Using getchar function, read the character and stored in the string [] array. 4. The string [] array is write into a file and close it. 5. Then the file is opened for read only mode and read the characters and displayed it and close the file. 6. Stop the program.

27

Program: #include<sys/stat.h> #include<stdio.h> #include<fcntl.h> #include<sys/types.h> int main() { int n,i=0; int f1,f2; char c,strin[100]; f1=open("data",O_RDWR|O_CREAT|O_TRUNC); while((c=getchar())!='\n') { strin[i++]=c; } strin[i]='\0'; write(f1,strin,i); close(f1); f2=open("data",O_RDONLY); read(f2,strin,0); printf("\n%s\n",strin); close(f2); return 0; }

28

OUTPUT:

[cs2002@localhost ~]$ cc isc.c [cs2002@localhost ~]$ ./a.out HAI WELCOME TO CSE

HAI WELCOME TO CSE [cs2002@localhost ~]$

Result:

Thus the I/O system call program was executed.

29

Ex.No:3

SIMULATION OF UNIX COMMANDS

Aim:

To write a program for simulation of unix commands ls and grep.

DESCRIPTION

The ls Command Syntax: ls [options] [names] Description: "ls" stands for list. It is used to list information about files and directories. Examples: ls This is the basic "ls" command, with no options. It provides a very basic listing of the files in your current working directory. Filenames beginning with a decimal are considered hidden files, and they are not shown. ls -a The -a option tells the ls command to report information about all files, including hidden files. ls -l The -l option tells the "ls" command to provide a long listing of information about the files and directories it reports. The long listing will provide important information about file permissions, user and group ownership, file size, and creation date. ls -al This command provides a long listing of information about all files in the current directory. It combines the functionality of the -a and -l options. This is probably the most used version of the ls command. ls -al /usr 30

This command lists long information about all files in the "/usr" directory. ls -alR /usr | more This command lists long information about all files in the "/usr" directory, and all sub-directories of /usr. The -R option tells the ls command to provide a recursive listing of all files and sub-directories. ls -ld /usr Rather than list the files contained in the /usr directory, this command lists information about the /usr directory itself (without generating a listing of the contents of /usr). This is very useful when you want to check the permissions of the directory, and not the files the directory contains. The grep Command Syntax: grep flag PatternList filename The grep command is a Unix command that is used to search for patterns within one or more files. It displays the name of the file that contains the matched line. Following is a list of some flags used with the grep command: Flag Description -c Displays a count of matching lines. -f Specifies a file containing search patterns. -p Displays the entire paragraph containing matched lines. -v Displays all lines not matching the specified pattern. PatternList Specifies one or more patterns to be used during the search. File Specifies the name of the file that is to be searched for the pattern.

Algorithm: 1. Start the program. 2. Enter the options. 3. If the option is 1 call ls command and it display the files. 4. If the option is 2 call gerp command and match the given pattern with the read word and if it matches, display the line of occurance. 5. If the option is 3 call cp command. 6. If the option is 4 call rm command. 7. Stop the program.

31

Program: #include<stdio.h> main() { char c; int n; printf("1.list of files in the directory\n2.list the lines\n3.copy\n4.remove\n"); scanf("%d",&n); switch(n) { case 1: system("ls"); break; case 2: system("grep argc lsgp.c"); break; case 3: system(" cp lsgp.c gpls.c"); printf("the file is copied"); break; case 4: system("rm lsgp.c"); printf("the file is deleted"); break; } }

32

OUTPUT: [it53@localhost ~]$ cc lsgp.c [it53@localhost ~]$ ./a.out 1.list of files in the directory 2.list the lines 3.copy 4.remove 1 3q bit.c ftp.c ospf1.c praba.c rarp.c smp.c sort.sh

a.out forkexec.c io.c praba1.sh praba.sh sample sorting.sh syscall.c [it53@localhost ~]$ ./a.out 1.list of files in the directory 2.list the lines 3.copy 4.remove 2 system("grep argc lsgp.c"); [it53@localhost ~]$ ./a.out 1.list of files in the directory 2.list the lines 3.copy 4.remove 3 the file is copied[it53@localhost ~]$ ./a.out 1.list of files in the directory 2.list the lines 3.copy 4.remove 4 the file is deleted

33

Result:

Thus the program for simulation of unix commands ls and grep was executed.

34

Ex.No:4(a) IMPLEMENTATION OF FCFS SCHEDULING Aim:

To write the program for first come first serve scheduling.

DESCRIPTION

First-Come, First-Served (FCFS) Scheduling

35

Algorithm:

1. Start the program. 2. Get the number of processes and their burst time. 3. Initialize the waiting time for process 1 is 0. 4. The waiting time and turn around time for other processes are calculated as p[i].wt=p[i-1].bt+p[i-1].wt; p[i].tt=p[i].bt+p[i].wt; 5. The waiting time and turn around time for all the processes are summed and then the average waiting time and turn around time are calculated. 6. The average waiting time and turn around time are displayed. 7. Stop the program.

36

Program: #include<stdio.h> #include<conio.h> #include<stdlib.h> struct process { int pid; int wt,tt,bt; } p[100]; void main() { int tottt,totwt,avgtt,avgwt,i,j,n; clrscr(); printf("\nEnter Number of process"); scanf("\n%d",&n); for(i=1;i<=n;i++) { p[i].pid=i; printf("\nEnter %dst Burst Time:",i); scanf("\n%d",&p[i].bt); } p[1].wt=0; p[1].tt=p[1].bt+p[1].wt; i=2; while(i<=n) { p[i].wt=p[i-1].tt; p[i].tt=p[i].bt+p[i].wt; i++; } 37

totwt=tottt=0; i=1; printf("\n\t============================="); printf("\n\tProcess id\tBT\tWT\tTT"); printf("\n\t============================="); while(i<=n) { printf("\n\t%d\t%d\t%d\t%d\t",p[i].pid,p[i].bt,p[i].wt,p[i].tt); totwt=p[i].wt+totwt; tottt=p[i].tt+tottt; i++; } totwt=totwt/n; tottt=tottt/n; printf("\n\n\n\tAVGWT\tAVGTT"); printf("\n\t%d\t%d",totwt,tottt); getch(); }

38

OUTPUT:

Enter Number of process3 Enter 1st Burst Time:12 Enter 2st Burst Time:34 Enter 3st Burst Time:56

=============================== Process id BT WT TT

=============================== 1 2 3 12 34 56 0 12 46 12 46 102

AVGWT AVGTT 19 53

Result:

Thus the program for first come first serve algorithm was executed. 39

Ex.No:4(b) IMPLEMENTATION OF SJF SCHEDULING

Aim:

To write the program for shortest job first scheduling.

DESCRIPTION Associate with each process the length of its next CPU burst. Use these lengths to schedule the process with the shortest time Two schemes: non preemptive burst preemptive if a new process arrives with CPU burst length less than remaining time of current once CPU given to the process it cannot be preempted until completes its CPU

executing process, preempt. This scheme is known as the Shortest-Remaining-Time-First (SRTF) SJF is optimal gives minimum average waiting time for a given set of processes

40

Algorithm:

1. Start the program. 2. Get the number of processes and their burst time. 3. Initialize the waiting time for process 1 is 0. 4. The processes are stored according to their burst time. 5. The waiting time and turn around time for other processes are calculated as p[i].wt=p[i-1].bt+p[i-1].wt; p[i].tt=p[i].bt+p[i].wt; 6. The waiting time and turn around time for all the processes are summed and then the average waiting time and turn around time are calculated. 7. The average waiting time and turn around time are displayed. 8. Stop the program.

41

Program: #include<stdio.h> #include<conio.h> #include<stdlib.h> struct process { int pid; int wt,tt,bt; } p[100]; void main() { struct process temp;

int tottt,totwt,avgtt,avgwt,i,j,n; clrscr(); printf("\nEnter Number of process"); scanf("\n%d",&n); for(i=1;i<=n;i++) { p[i].pid=i; printf("\nEnter %d Burst Time:",i); scanf("\n%d",&p[i].bt); } for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { if(p[i].bt>p[j].bt) { /*temp.pid=p[j].pid; 42

p[j].pid=p[i].pid; p[i].pid=temp.pid; temp.bt=p[j].bt; p[j].bt=p[i].bt; p[i].bt=temp.bt; */ temp=p[j]; p[j]=p[i]; p[i]=temp; }}} p[1].wt=0; p[1].tt=p[1].bt+p[1].wt; i=2; while(i<=n) { p[i].wt=p[i-1].tt; p[i].tt=p[i].bt+p[i].wt; i++; } totwt=tottt=0; i=1; printf("\n\t================================="); printf("\n\t Process id \tBT\tWT\tTT"); printf("\n\t================================"); while(i<=n) { printf("\n\t%d\t%d\t%d\t%d\t",p[i].pid,p[i].bt,p[i].wt,p[i].tt); totwt=p[i].wt+totwt; tottt=p[i].tt+tottt; i++; } totwt=totwt/n; 43

tottt=tottt/n; printf("\n\n\n\tAVGWT\tAVGTT"); printf("\n\t%d\t%d",totwt,tottt); getch(); }

OUTPUT Enter Number of process:5 Enter 1 Burst Time: 8 Enter 2 Burst Time: 4 Enter 3 Burst Time: 7 Enter 4 Burst Time: 2 Enter 5 Burst Time: 9 =================================== Process id BT WT TT

=================================== 4 2 3 1 5 2 4 7 8 9 0 2 6 13 21 2 6 13 21 30

AVGWT 8

AVGTT 14

Result: Thus the program for shortest job first algorithm was executed.

44

Ex.No:5(a) IMPLEMENTATION OF PRIORITY SCHEDULING

Aim:

To write the program to perform priority scheduling.

DESCRIPTION A priority number (integer) is associated with each process The CPU is allocated to the process with the highest priority (smallest integer => highest priority) - Preemptive - non preemptive SJF is a priority scheduling where priority is the predicted next CPU burst time Problem Starvation low priority processes may never execute Solution Aging as time progresses increase the priority of the process

Algorithm:

1. Start the program. 2. Get the number of processes, their burst time and priority. 3. Initialize the waiting time for process 1 is 0. 4. Based upon the priority processes are arranged. 5. The waiting time and turn around time for other processes are calculated as p[i].wt=p[i-1].bt+p[i-1].wt; p[i].tt=p[i].bt+p[i].wt; 6. The waiting time and turn around time for all the processes are summed and then the average waiting time and turn around time are calculated. 7. The average waiting time and turn around time are displayed. 8. Stop the program.

45

Program: #include<stdio.h> #include<conio.h> #include<stdlib.h> struct process { int pid; int wt,tt,bt,prior; } p[100],temp; void main() { int tottt,totwt,avgtt,avgwt,i,j,n; clrscr(); printf("\nEnter Number of process"); scanf("\n%d",&n); for(i=1;i<=n;i++) { p[i].pid=i; printf("\nEnter %dst Burst Time:",i); scanf("\n%d",&p[i].bt); printf("\nEnter %dpriority",i); scanf("\n%d",&p[i].prior); } for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { if(p[i].prior>p[j].prior) { temp=p[j]; 46

p[j]=temp; }}} p[1].wt=0; p[1].tt=p[1].bt+p[1].wt; i=2; while(i<=n) { p[i].wt=p[i-1].tt; p[i].tt=p[i].bt+p[i].wt; i++; } totwt=tottt=0; i=1; printf("\n\t==============================="); printf("\n\tPSSID\tBT\tWT\tTT"); printf("\n\t==============================="); while(i<=n) { printf("\n\t%d\t%d\t%d\t%d\t",p[i].pid,p[i].bt,p[i].wt,p[i].tt); totwt=p[i].wt+totwt; tottt=p[i].tt+tottt; i++; } totwt=totwt/n; tottt=tottt/n; printf("\n\n\n\tAVGWT\tAVGTT"); printf("\n\t%d\t%d",totwt,tottt); getch(); }

47

OUTPUT:

Enter Number of process3

Enter 1st Burst Time:5

Enter 1priority3

Enter 2st Burst Time:7

Enter 2priority1

Enter 3st Burst Time:8

Enter 3priority2

=============================== PSSID BT WT TT

=============================== 1 2 3 5 7 8 0 5 12 5 12 20

AVGWT 5

AVGTT 12

Result:

Thus the program for priority scheduling was executed. 48

Ex.No:5(b) IMPLEMENTATION OF ROUND ROBIN SCHEDULING

Aim:

To write a program for Round Robin Scheduling.

DESCRIPTION Each process gets a small unit of CPU time (time quantum), usually 10-100 milliseconds. After this time has elapsed, the process is preempted and added to the end of the ready queue. If there are n processes in the ready queue and the time quantum is q, then each process gets 1/n of the CPU time in chunks of at most q time units at once. No process waits more than (n-1)q time units. Performance q large q small FIFO q must be large with respect to context switch, otherwise overhead is too high

49

Algorithm:

1. Start the program. 2. Get the number of processes, their burst time and time slice for each process. 3. Calculate the total burst time. 4. To check whether the burst time of process is less then the time slice, the required time only allotted to the process. 5. If the burst time of process is greater than the time slice one time slice is allotted for the process and burst time is subtracted by one time slice. 6. Step 4 and 5 is repeated up to process burst time is 0. 7. The waiting time and turn around time for all the processes are summed and then the average waiting time and turn around time are calculated. 8. The average waiting time and turn around time are displayed. 9. Stop the program.

50

Program: #include<stdio.h> #include<conio.h> struct process { int pid,bt,tt,wt; }; int main() { struct process x[10],p[30]; int i,j,k,tot=0,m,n; float wttime=0.0,tottime,a1,a2; clrscr(); printf("\nEnter No.of process\t"); scanf("%d",&n); for(i=1;i<=n;i++) { x[i].pid=i; printf("Enter The Burst Time \t"); scanf("%d",&x[i].bt); tot=tot+x[i].bt; } printf("Total Burst Time:\t%d",tot); p[0].tt=0; k=1; printf("\nEnter The Time Slice:\t"); scanf("%d",&m); for(j=1;j<=tot;j++) { for(i=1;i<=n;i++) { 51

if(x[i].bt!=0) { p[k].pid=i; if(x[i].bt-m<0) { p[k].wt=p[k-1].tt; p[k].bt=x[i].bt; p[k].tt=p[k].wt+x[i].bt; x[i].bt=0; k++; } else { p[k].wt=p[k-1].tt; p[k].tt=p[k].wt+m; x[i].bt=x[i].bt-m; k++; }}} } printf("\nprocess id\ttwt\ttt"); for(i=1;i<k;i++) { printf("\n\t%d\t%d\t%d",p[i].pid,p[i].wt,p[i].tt); wttime=wttime+p[i].wt; tottime=tottime+p[i].tt; a1=wttime/n; a2=tottime/n; } printf("\n\nAverage Waiting Time:\t%f",a1); printf("\n\nAverage TurnAround Time:\t%f",a2); getch(); 52

return 0; }

OUTPUT:

Enter No.of process Enter The Burst Time Enter The Burst Time Enter The Burst Time Total Burst Time:

3 5 6 7 18

Enter The Time Slice: 3

process id 1 2 3 1 2 3 3

twt 0 3 6 9 11 14 17

tt 3 6 9 11 14 17 18

Average Waiting Time: 20.000000

Average TurnAround Time:

26.000000

Result:

Thus the program for Round Robin Scheduling was executed.

53

Ex.No:6(a)

INTERPROCESS COMMUNICATION USING SHARED MEMORY


Aim:

To write a program for interprocess communication using shared memory.

DESCRIPTION A shared memory is an extra piece of memory that is attached to some address spaces for their owners to use. As a result, all of these processes share the same memory segment and have access to it. Consequently, race conditions may occur if memory accesses are not handled properly. The following figure shows two processes and their address spaces. The yellow rectangle is a shared memory attached to both address spaces and both process 1 and process 2 can have access to this shared memory as if the shared memory is part of its own address space. In some sense, the original address space is "extended" by attaching this shared memory.

Algorithm: 1. Start the program 2. Create the child process using fork() 3. Create the shared memory for parent process using shmget() system call 4. Now allow the parent process to write inn shared memory using shmpet pointer which is return type of shmat() 5. Now across and attach the same shared memory to the child process 6. The data in the shared memory is read by the child process using the shnot pointer 7. Now, detach and rebase the shared memory 8. Stop the program 54

Program: #include<sys/types.h> #include<sys/shm.h> #include<sys/ipc.h> main() { int shmid; key_t key=0*10; shmid=shmget(key,100,IPC_CREAT|0666); if(shmid<0) printf("\nfirst SHMID failed\n"); else printf("\n first SHMID succeded id=%d\n",shmid); shmid=shmget(key,101,IPC_CREAT|0666); if(shmid<0) printf("\nsecond SHMID failed\n"); else printf("\n secondt SHMID succeded id=%d\n",shmid); shmid=shmget(key,90,IPC_CREAT|0666); if(shmid<0) printf("\nthird SHMID failed\n"); else printf("\n third SHMID succeded id=%d\n",shmid); }

55

OUTPUT:

[cse2@localhost ~]$ cc share.c [cse2@localhost ~]$ ./a.out

first SHMID succeded id=589833

secondt SHMID succeded id=622604

third SHMID succeded id=655373 [cse2@localhost ~]$

Result:

Thus the interprocess communication using shared memory was successfully executed 56

Ex.No:6(b)

INTER PROCESS COMMUNICATION USING PIPE PROCESSING


Aim:

To write a program for interprocess communication using pipe processing.

DESCRIPTION Using pipes for establishing a communication between two processes. As a first step we need to identify two executables that need to communicate. As an example, consider a case where one process gets a character string input and communicates it to the other process which reverses strings. Then we have two processes which need to communicate. Next we define a pipe and connect it between the processes to facilitate communication. One process gets input strings and writes into the pipe. The other process, which reverses strings, gets its input (i.e. reads) from the pipe. Figure explains how the pipes are used. As shown in the upper part of the figure, a pipe has an input end and an output end. One can write into a pipe from the input end and read from the output end. A pipe descriptor, therefore, has an array that stores two pointers. One pointer is for its input end and the other is for its output end. When a process defines a pipe it gets both the addresses, as shown in the middle part of Figure. Let us suppose array pp is used to store the descriptors. pp[0] stores the write end address and pp[1] stores the read end address. Suppose two processes, Process A and Process B, need to communicate, then it is imperative that the process which writes closes its read end of the pipe and the process which read closes its write end of the pipe. Essentially, for a communication from Process A to process B the following should happen. Process A should keep its write end open and close read end of the pipe. Similarly, Process B should keep its read end open and close its write end.

Let us now describe how we may accomplish this.

1. First we have a parent process which declares a pipe in it. 2. Next we spawn two child processes. Both of these would get the pipe definition which we have defined in the parent. The child processes, as well as the parent, have both the write and read 57

ends of the pipe open at this time. 3. Next, one child process, say Process A, closes its read end and the other child process, Process B, closes its write end. 4. The parent process closes both write and read ends. 5. Next, Process A is populated with code to get a string and Process B is populated to reverse a string. With the above arrangement the output from Process A is piped as input to Process B.

The programs given below precisely achieve this. In reading the programs, the following interpretations have to be borne in mind: 1. The pipe is defined by the declaration pipe(p_des). 2. The dup command replaces the standard I/O channels by pipe descriptors. 3. The execlp command is used to populate the child process with the desired code. 4. The close command closes the appropriate ends of the pipe. 5. The get_str and rev_str processes are pre-compiled to yield the required executables.

58

Algorithm:

1. Start the program. 2. Create the child process using fork(). 3. Create the pipe structure using pipe(). 4. Now close the read end of the parent process using close(). 5. Write the data in the pipe using write(). 6. Now close the write end of child process using close(). 7. Read the data in the pipe using read(). 8. Display the string. 9. Stop the program.

59

Program: #include<unistd.h> main() { int fd[3],pid; char *msg=("OS LAB\n"); char buff[25]; pipe(fd); pid=fork(); if(pid==0) { puts("child process\n"); close(fd[0]); write(fd[1],msg,30); } else { sleep(1); puts("parent process\n"); close(fd[1]); read(fd[0],buff,30); printf("%s",buff); } }

60

OUTPUT: [cse2@localhost ~]$ cc pipe.c [cse2@localhost ~]$ ./a.out child process

parent process

OS LAB [cse2@localhost ~]$

Result:

Thus the interprocess communication using pipe process was successfully executed. 61

Ex.No:7 PRODUCER - CONSUMER PROBLEM USING SEMAPHORE

Aim:

To write a program for producer/consumer problem using semaphores.

DESCRIPTION This is an illustration of a solution to the classic producer-consumer (bounded-buffer) problem using semaphores. CONCEPT Producers produce items to be stored in the buffer. Consumers remove and consume

items which have been stored. Mutual exclusion must be enforced on the buffer itself. Moreover, producers can store only when there is an empty slot, and consumers can remove only when there is a full slot. Three semaphores are used. The binary semaphore mutex controls access to the buffer itself. The counting semaphore empty keeps track of empty slots, and the counting semaphore full keeps track of full slots. In this example, the buffer is implemented as an array of size MAX treated as a circular (ring) buffer. Variables in and out give the index of the next position for putting in and taking out (if any). Variable count gives the number of items in the buffer. Algorithm: 1. Start the program. 2. Declare the variables in the type of pthread_t as tid_produce tid_consume. 3. Declare a structure for semaphore variables. 4. During run time read the number of items to be produced and consumed. 5. Declare and define semaphore function for creation and destroy. 6. Define producer function. 7. Define consumer function. 8. Call producer and consumer function. 9. Stop the execution.

62

Program: #include <stdio.h> #include <semaphore.h> #include <pthread.h> #define NBUFF 10 int nitems; struct { int buff[NBUFF]; sem_t mutex, nempty, nstored; } shared; void *produce (void *); void *consume (void *); int main(int argc, char **argv) { pthread_t tid_produce, tid_consume; if(argc !=2) { printf("Useage: filename <nitems> "); return 0; } printf ("\n\n Producer - Consumer Problem using Semaphore\n"); printf (" -------------------------------------------\n\n"); nitems=atoi(argv[1]); sem_init(&shared.mutex,0,1); sem_init(&shared.nempty,0,NBUFF); sem_init(&shared.nstored,0,0); pthread_setconcurrency(2); pthread_create(&tid_produce,NULL,produce,NULL); pthread_create(&tid_consume,NULL,consume,NULL); pthread_join(tid_produce,NULL); pthread_join(tid_consume,NULL); 63

sem_destroy(&shared.mutex); sem_destroy(&shared.nempty); sem_destroy(&shared.nstored); } void *produce (void *arg) { int i; for(i=0;i<nitems;i++) { sem_wait(&shared.nempty); sem_wait(&shared.mutex); shared.buff[i % NBUFF]=i; printf ("\tProducer....."); printf ("buff[%d] = %d\n\n",i,shared.buff[i % NBUFF]); sem_post(&shared.mutex); sem_post(&shared.nstored); sleep(3); } return NULL; } void *consume (void *arg) { int i; for(i=0;i<nitems;i++) { sem_wait(&shared.nstored); sem_wait(&shared.mutex); printf("\tConsumer....."); printf("buff[%d] = %d\n\n\n",i,shared.buff[i%NBUFF]); sem_post(&shared.mutex); sem_post(&shared.nempty); 64

sleep(3); } return NULL; }

OUTPUT:

[root@NS2-05 root]# cc -pthread prod_cons.c [root@NS2-05 root]# ./a.out 4

Producer - Consumer Problem using Semaphore -------------------------------------------

Producer.....buff[0] = 0 Consumer.....buff[0] = 0

Producer.....buff[1] = 1 Consumer.....buff[1] = 1

Producer.....buff[2] = 2 Consumer.....buff[2] = 2

Producer.....buff[3] = 3 Consumer.....buff[3] = 3

Result:

Thus the program to implement producer and consumer problem using semaphores was executed.

65

Ex.No: 8 MEMORY MANAGEMENT SCHEMES I FIRST FIT BEST FIT

Aim:

To write a program for first fit and best fit algorithm for memory management.

DESCRIPTION
Memory Management Algorithms

In an environment that supports dynamic memory allocation, the memory manager must keep a record of the usage of each allocatable block of memory. This record could be kept by using almost any data structure that implements linked lists. An obvious implementation is to define a free list of block descriptors, with each descriport containing a pointer to the next descriptor, a pointer to the block, and the length of the block. The memory manager keeps a free list pointer and inserts entries into the list in some order conducive to its allocation strategy. A number of strategies are used to allocate space to the processes that are competing for memory. First Fit Another strategy is first fit, which simply scans the free list until a large enough hole is found. Despite the name, first-fit is generally better than best-fit because it leads to less fragmentation. Small holes tend to accumulate near the beginning of the free list, making the memory allocator search farther and farther each time.Solution: Next Fit Best Fit The allocator places a process in the smallest block of unallocated memory in which it will fit. It requires an expensive search of the entire free list to find the best hole. More importantly, it leads to the creation of lots of little holes that are not big enough to satisfy any requests. This situation is called fragmentation, and is a problem for all memory-management strategies, although it is 66

particularly bad for best-fit. One way to avoid making little holes is to give the client a bigger block than it asked for. For example, we might round all requests up to the next larger multiple of 64 bytes. That doesn't make the fragmentation go away, it just hides it.

Unusable space in the form of holes is called external fragmentation Unusable space in the form of holes is called external fragmentation

Algorithm:

1. Start the program. 2. Get the number of segments and size. 3. Get the memory requirement and select the option. 4. If the option is 2 call first fit function. 5. If the option is 1 call best fit function. 6. Otherwise exit. 7. For first fit, allocate the process to first possible segment which is free. 8. For best fit, do the following steps. a. Sorts the segments according to their sizes. b. Allocate the process to the segment which is equal to or slightly greater than the process size. 9. Stop the program.

67

Program: #include<stdio.h> #include<conio.h> #define MAXSIZE 25 void printlayout(int[],int ); int firstfit(int[],int, int); int bestfit(int[],int, int); void main() { int i,a[25],n,req,choice,pos,ch; clrscr(); printf("How MAny Segments"); scanf("%d",&n); for(i=0;i<n;i++) { printf("Segent Size"); scanf("%d",&a[i]); } loop: printf("How Much Is Your Memory Requirment"); scanf("%d",&req); printf("\n1.Bestfit\n2.Firstfit\n3.Exit\n"); printf("Enter Your Choice\n"); scanf("%d",&choice); switch(choice) { case 1: pos=bestfit(a,n,req); break; case 2: pos=firstfit(a,n,req); 68

break; } printf("\tBestfit and Firstfit Algorithm\n"); printf("\t______________________________\n\n"); printlayout(a,n); printf("Your Memory Requirment is :%d\n\n",req); printf("Alloted Memory Region is:%d\n\n",a[pos]); a[pos]=0; printf("Do You Want To Continue 1/0"); scanf("%d",&ch); if(ch==1) goto loop; getch(); } void printlayout(int a[],int n) { int i,j; printf("\t\tMemory Free List"); printf("\n\t\t_______________\n\n"); printf("\t\t|~~~|\n"); for(i=0;i<n;i++) { if(a[i]!=0) { for(j=1;j<=(a[i]/100);j++) printf("\t\t| |\n"); printf("\t\t| %d|\n",a[i]); printf("\t\t|---|\n"); }} printf("\n\n"); } 69

int firstfit(int a[],int n,int r) { int i; for(i=0;i<n;i++) if(a[i]>=r) break; return i; } int bestfit(int a[],int n,int r) { int b[25],i,j,temp,val; for(i=0;i<n;i++) b[i]=a[i]; for(i=0;i<n-1;i++) for(j=i;j<n-1;j++) if(b[i]>b[j]) { temp=b[i]; b[i]=b[j]; b[j]=temp; } for(i=0;i<n;i++) if(b[i]>=r) break; val=b[i]; for(i=0;i<n;i++) if(a[i]==val) break; return i; }

70

OUTPUT: How Many Segments4 Segent Size500 Segent Size200 Segent Size300 Segent Size400 How Much Is Your Memory Requirment200 1.Bestfit 2.Firstfit 3.Exit Enter Your Choice 1 Bestfit and Firstfit Algorithm ___________________________________ Memory Free List ___________________________________

|~~~| | | | | | | | |

|500| | --- | | | | |

|200| | --- | | | | | | |

|300| 71

| --- | | | | | | | | |

|400| | --- |

Your Memory Requirment is :200

Alloted Memory Region is:200

Do You Want To Continue 1/0 1 How Much Is Your Memory Requirment250

1.Bestfit 2.Firstfit 3.Exit Enter Your Choice 1 Bestfit and Firstfit Algorithm ___________________________________ Memory Free List ___________________________________

|~~~| | | | | | |

|500| 72

| --- | | | | |

|300| | --- | | | | | | |

|400| | --- |

Your Memory Requirment is :250

Alloted Memory Region is:300

Do You Want To Continue 1/0

Result:

Thus the program for best fit and first fit algorithm for memory management was executed.

73

Ex.No:9 MEMORY MANAGEMENT SCHEMES II PAGE REPLACEMENT Aim:

To write a program for page replacement algorithms (FIFO and LRU) for memory management.

DESCRIPTION Page replacement algorithms are used to decide what pages to page out when a page needs to be allocated. This happens when a page fault occurs and free page cannot be used to satisfy allocation

FIFO: The frames are empty in the beginning and initially no page fault occurs so it is set to minus one. When a page fault occurs the page reference string is brought into memory. The operating system keeps track of all the pages in memory, herby keeping track of the most recently arrived and the oldest one. If the page in the page reference string is not in memory, the page fault is incremented and the oldest page is replaced. If the page in the page reference string is in the memory, take the next page without calculating the page fault. Take the next page in the page reference string and check if the page is already present in the memory or not. Repeat the process until all the pages are referred and calculate the page fault for all those pages in the page reference string for the number of available frames.

LRU : A good approximation to the optimal algorithm is based on the observation that pages that have been heavily used in the last few instructions will probably be heavily used again in the next few. Conversely, pages that have not been used for ages will probably remain unused for a long time. This idea suggests a realizable algorithm: when a page fault occurs, throw out the page that has been unused for the longest time. This strategy is called LRU (Least Recently Used) paging.

74

Algorithm:

1. Start the program 2. Obtain the number of sequences, number of frames and sequence string from the user 3. Now when a page is not in the frame comes, increment the number of page fault and remove the page that come in the first in FIFO algorithm 4. In LRU algorithm, when a page fault occurs, the page which most recently used is removed 5. Display the number of faults 6. Stop the program

75

Program: #include<stdio.h> int m,n,i,j,k,flag,count=0,refer[100],page_frame[100][2],fault=0,min,no_frames; void replace(int z) { for(i=0;i<n;i++) { flag=1; for(j=0;j<no_frames;j++) if(refer[i]==page_frame[j][0]) { m=j; flag=0; } if(flag) { fault++; min=32000; for(j=0;j<no_frames;j++) if(page_frame[j][1]<min) { min=page_frame[j][1]; k=j; } page_frame[k][0]=refer[i]; page_frame[k][1]=++count; for(j=0;j<no_frames;j++) printf("%d",page_frame[j][0]); printf("\n"); } else 76

{ printf("no page fault\n"); if(z==2) page_frame[m][1]=++count; } } printf("number of page fault is:%d\n",fault); } int main() { printf("\nEnter the number of reference:"); scanf("%d",&n); printf("\nEnter the number of frames:"); scanf("%d",&no_frames); printf("\nEnter the reference string:"); for(i=0;i<n;i++) scanf("%d",&refer[i]); printf("\t\t\tFIFO ALGORITHM \n"); for(i=0;i<no_frames;i++) { page_frame[i][0]=-1; page_frame[i][1]=count; } replace(1); fault=0; count=0; printf("\t\t\tLRU ALGORITHM \n"); for(i=0;i<no_frames;i++) { page_frame[i][0]=-1; page_frame[i][1]=count; 77

} replace(2); return 0; getch(); }

78

OUTPUT:

Enter the number of reference:10 Enter the number of frames:3 Enter the reference string:7 0 1 2 0 3 0 4 2 6 FIFO ALGORITHM 7 -1 -1 7 0 -1 7 0 1 2 0 1 no page fault 2 3 1 2 3 0 4 3 0 4 2 0 4 2 6 number of page fault is:9 LRU ALGORITHM 7 -1 -1 7 0 -1 7 0 1 2 0 1 no page fault 2 0 3 no page fault 4 0 3 4 0 2 4 6 2 number of page fault is:8

79

Result:

Thus the program for page replacement algorithms for memory management was successfully executed.

80

Ex.No:10

FILE ALLOCATION TECHNIQUE-CONTIGUOUS

AIM: To Write a C Program to implement file allocation technique.

DESCRIPTION File Allocation Methods


One main problem in file management is how to allocate space for files so that disk space is utilized effectively and files can be accessed quickly. Three major methods of allocating disk space are: * Contiguous Allocation * Linked Allocation * Indexed Allocation. Each method has its advantages and disadvantages. Accordingly, some systems support all three (e.g. Data General's RDOS). More commonly, a system will use one particular method for all files. Contiguous File Allocation

Each file occupies a set of contiguous block on the disk Allocation using first fit/best fit. A need for compaction Only starting block and length of file in blocks are needed to work with the file Allows random access Problems with files that grow

ALGORITHM: 1. Start the process 2. Declare the necessary variables 3. Get the number of files 4.Get the total no. of blocks that fit in to the file 5. Display the file name, start address and size of the file. 6.Stop the program.

81

PROGRAM: #include<stdio.h> void main() { int i,j,n,block[20],start: printf(Enter the no. of file:\n); scanf(%d,&n); printf(Enter the number of blocks needed for each file:\n); for(i=0,i<n;i++) scanf(%d,&block[i]); start=0; printf(\t\tFile name\tStart\tSize of file\t\t\n); printf(\n\t\tFile1\t\t%d\t\t\t%d\n,start,block[0]); for(i=2;i<=n;i++) { Start=start+block[i-2]; Printf(\t\tFile%d\t\t%d\t\tD\n,i,start,block[i-1]); } }

82

Output Enter the number of file:4 Enter the number of blocks needed for each file: 3 5 6 1 Filename start size of file File 1 File 2 File 3 File 4 0 3 8 14 3 5 6 1

Result: Thus the program for file allocation technique has been done successfully. 83

VIVA VOCE 1. What is an Operating system? An operating system is a program that manages the computer hardware. It also provides a basis for application programs and act as an intermediary between a user of a computer and the computer hardware. It controls and coordinates the use of the hardware among the various application programs for the various users. 2. What is the Kernel? A more common definition is that the OS is the one program running at all times on the computer, usually called the kernel, with all else being application programs. 3. What are Batch systems? Batch systems are quite appropriate for executing large jobs that need little interaction. The user can submit jobs and return later for the results. It is not necessary to wait while the job is processed. Operators batched together jobs with similar needs and ran them through the computer as a group. 4. What do you mean by Time-sharing systems? Time-sharing or multitasking is a logical extension of multiprogramming. It allows many users to share the computer simultaneously. The CPU executes multiple jobs by switching among them,but the switches occur so frequently that the users can interact with each program while it is running. 5. What are multiprocessor systems & give their advantages? Multiprocessor systems also known as parallel systems or tightly coupled systems are systems that have more than one processor in close communication, sharing the computer bus, the clock and sometimes memory & peripheral devices. Their main advantages are Increased throughput Economy of scale Increased reliability

84

6. What is a process? A process is a program in execution. It is the unit of work in a modern operating system. A process is an active entity with a program counter specifying the next instructions to execute and a set of associated resources. It also includes the process stack, containing temporary data and a data section containing global variables. 7. What is a process state and mention the various states of a process? As a process executes, it changes state. The state of a process is defined in part by the current activity of that process. Each process may be in one of the following states: New Running Waiting Ready Terminated . Compare user threads and kernel threads. User threads User threads are supported above the Kernel threads are supported directly kernel and are implemented by a thread library at the user level Thread creation & scheduling are done in the user space, without kernel intervention. Therefore they are fast to create and manage Blocking system call will cause the entire process to block 8. What is the use of fork and exec system calls? Kernel threads Thread creation, scheduling and management are done by the operating If the thread performs a blocking system call, the kernel can schedule another thread in the application for execution fork by one of the two processes to replace the process memory space with a new program. Fork is a system call by which a new process is created. Exec is also a system call, which is used after a

85

9. Define CPU scheduling. CPU scheduling is the process of switching the CPU among various processes. CPU scheduling is the basis of multi programmed operating systems. By switching the CPU among processes, the operating system can make the computer more productive. 10. What is preemptive and non preemptive scheduling? Under non preemptive scheduling once the CPU has been allocated to a process, the process keeps the CPU until it releases the CPU either by terminating or switching to the waiting state. Preemptive scheduling can preempt a process which is utilizing the CPU in between its execution and give the CPU to another process. 11. Define throughput? Throughput in CPU scheduling is the number of processes that are completed per unit time. For long processes, this rate may be one process per hour; for short transactions, throughput might be 10 processes per second. 12. What is turnaround time? Turnaround time is the interval from the time of submission to the time of completion of a process. It is the sum of the periods spent waiting to get into memory, waiting in the ready queue, executing on the CPU, and doing I/O. 13. What is semaphores? A semaphore S is a synchronization tool which is an integer value that, apart from initialization, is accessed only through two standard atomic operations; wait and signal. Semaphores can be used to deal with the n-process critical section problem. It can be also used to solve various synchronization problems. The classic definition of wait wait (S) { } while (S<=0) S--; The classic definition of signal signal (S) { 86

} S++; ; 14. Define deadlock prevention. Deadlock prevention is a set of methods for ensuring that at least one of the four necessary conditions like mutual exclusion, hold and wait, no pre- emption and circular wait cannot hold. By ensuring that that at least one of these conditions cannot hold, the occurrence of a deadlock can be prevented. 15. Define deadlock avoidance. An alternative method for avoiding deadlocks is to require additional information about how resources are to be requested. Each request requires the system consider the resources currently available, the resources currently allocated to each process, and the future requests and releases of each possible future deadlock. 16. What is the main function of the memory-management unit? The runtime mapping from virtual to physical addresses is done by a hardware device called a memory management unit (MMU). 17. What are the common strategies to select a free hole from a set of available holes? The most common strategies are a. First fit b. Best fit c. Worst fit 18. What is virtual memory? Virtual memory is a technique that allows the execution of processes that may not be completely in memory. It is the separation of user logical memory from physical memory. This separation provides an extremely large virtual memory, when only a smaller physical memory is available.

87

19. What is Demand paging? Virtual memory is commonly implemented by demand paging. In demand paging, the pager brings only those necessary pages into memory instead of swapping in a whole process. Thus it avoids reading into memory pages that will not be used anyway, decreasing the swap time and the amount of physical memory needed. 20. What is the various page replacement algorithms used for page replacement? a. FIFO page replacement b. Optimal page replacement c. LRU page replacement d. LRU approximation page replacement e. Counting based page replacement f. Page buffering algorithm. 21. What are the allocation methods of a disk space? Three major methods of allocating disk space which are widely in use are a. Contiguous allocation b. Linked allocation c. Indexed allocation

88

QUESTION SET

1.

Write programs using the following system calls of UNIX operating system: fork, exec, getpid, exit, wait, close, stat, opendir, readdir

2. 3. 4.

Write programs using the I/O system calls of UNIX operating system (open, read, write, etc) Write C programs to simulate UNIX commands like ls, grep, etc. Given the list of processes, their CPU burst times and arrival times, display/print the Gantt chart for FCFS and SJF. For each of the scheduling policies, compute and print the average waiting time and average turnaround time. (2 sessions)

5.

Given the list of processes, their CPU burst times and arrival times, display/print the Gantt chart for Priority and Round robin. For each of the scheduling policies, compute and print the average waiting time and average turnaround time. (2 sessions)

6.

Developing Application using Inter Process Communication (using shared memory, or message queues)

7.

Implement the Producer Consumer problem using semaphores (using UNIX system calls).

8. 9. 10.

Implement some memory management schemes I Implement some memory management schemes II Implement any file allocation technique (Linked, Indexed or Contiguous)

89

FUTURE DEVELOPMENT

Operating systems have evolved through the past years in a rapid manner. As the most important component in computers, changes in the operating systems have great consequences for users of computers. With the past changes in operating systems like the giant rise from command-line interface to the current graphical user interface, many common tasks became easier for the users. Currently computer users are faced with difficulties when installing new hardware's and some software's because of technical issues. In this context one can expect to see many new wizards implemented with the operating system. Wizards are software's, which give automated step-by-step instructions to carry out a task which otherwise would be very complicated for a basic computer user to carry out without technical assistance. Existing operating systems do carry admirable wizards for uninstalling and installing software's and hardware's (e.g. Windows 95. In the near future wizards will be integrated into the operating systems, which could carry out tasks like automatically cleaning up systems, deleting unnecessary files and further simplification of installment procedures of software's and hardware's, which can produce reports on what and what not a device or system can do. Wizards may also exist which may ask what to do at the moment, and even glance at the software you are currently installing and give suggestions on programs and documents for successfully accomplishing the task. Work is in progress to put out Operating systems integrated with browser features. Microsoft's strategy called Active Desktop was to use the browser metaphor for searching hard drives and surfing the Net. The future holds a date where HTML with Active X controls and Java might become THE file standards on a desktop and applications, their associated documents will be called through these HTML files. This means that the Network User Interface may replace the Graphical User Interface. Thus in the future you can access the web directly from the Operating System without opening a separate Web browser.

90

REFERENCES

1. Silberschatz, Galvin, and Gagne, Operating System Concepts, Sixth Edition, Wiley. India Pvt Ltd, 2003. 2. www.scribd.com/doc/38451142/CS2257 3. www.iannauniversity.com/.../cs2257-operating-systems-lab-.
4. www.webstatschecker.com/stats/.../operating_system_labmannual

91

Potrebbero piacerti anche