0% found this document useful (0 votes)
25 views

Operating Systems: Guru Tegh Bahadur Institute of Technology

The document provides details about implementing different memory allocation algorithms like First Fit, Best Fit, and Worst Fit for a fixed memory partition. It includes the theory, characteristics, and a sample C program to implement the First Fit algorithm. The program takes the block sizes of the main memory and process sizes as input, initializes all memory blocks as free, and then allocates processes to blocks by finding the first block that can accommodate it.

Uploaded by

alenwalker402
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views

Operating Systems: Guru Tegh Bahadur Institute of Technology

The document provides details about implementing different memory allocation algorithms like First Fit, Best Fit, and Worst Fit for a fixed memory partition. It includes the theory, characteristics, and a sample C program to implement the First Fit algorithm. The program takes the block sizes of the main memory and process sizes as input, initializes all memory blocks as free, and then allocates processes to blocks by finding the first block that can accommodate it.

Uploaded by

alenwalker402
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 46

GURU TEGH BAHADUR INSTITUTE OF

TECHNOLOGY

Operating Systems

Practical File

Artificial Intelligence & Data Science


Semester 5

Submitted to:- Submitted by :-


Ms Monika Srivastava Sukrati Sharma
01013211921
INDEX

S.NO. EXPERIMENT DATE SIGNATURE


C program to implement FCFS
1. scheduling algorithm.
C program to implement a round robin
2. scheduling algorithm.
Implementation of the following Memory
3. Allocation Methods for fixed partition
a) First Fit b) Worst Fit c) Best Fit
Program to implement reader/writer
4. problems using semaphores.
5. Program to implement Banker’s
algorithm for deadlock avoidance.
6. Study of basic UNIX commands and
various UNIX editors such as vi, ed, ex
and EMACS

7. Process Management

EXPERIMENT – 1
AIM: C program to implement FCFS scheduling algorithm.

THEORY:

FCFS is the first algorithm of CPU Process Scheduling Algorithm. In First Come First Serve
Algorithm what we do is to allow the process to execute in linear manner.

This means that whichever process enters process enters the ready queue first is executed
first. This shows that First Come First Serve Algorithm follows First In First Out (FIFO)
principle. The First Come First Serve Algorithm can be executed in Pre Emptive and Non Pre
Emptive manner.

The characteristics of FCFS CPU Process Scheduling are:

1. Implementation is simple.
2. Does not cause any causalities while using
3. It adopts a non pre-emptive and pre-emptive strategy.
4. It runs each procedure in the order that they are received.
5. Arrival time is used as a selection criterion for procedures.

Waiting Time = Turnaround Time – Burst Time


Turnaround Time = Completion Time – Arrival Time

FCFS Scheduling Algorithm:

1. Enter all the processes and their burst time.


2. Find waiting time, WT of all the processes.
3. For the 1st process, WT = 0.
4. For all the next processes i, WT[i] = BT[i-1] + WT[i-1].
5. Calculate Turnaround time = WT + BT for all the processes.
6. Calculate average waiting time = total waiting time/no. of processes.
7. Calculate average turnaround time = total turnaround time/no. of processes.

PROGRAM:
1. #include <stdio.h>
2. int main()
3. {
4. int pid[15];
5. int bt[15];
6. int n;
7. printf("Enter the number of processes: ");
8. scanf("%d",&n);
9.
10. printf("Enter process id of all the processes: ");
11. for(int i=0;i<n;i++)
12. {
13. scanf("%d",&pid[i]);
14. }
15.
16. printf("Enter burst time of all the processes: ");
17. for(int i=0;i<n;i++)
18. {
19. scanf("%d",&bt[i]);
20. }
21.
22. int i, wt[n];
23. wt[0]=0;
24.
25. //for calculating waiting time of each process
26. for(i=1; i<n; i++)
27. {
28. wt[i]= bt[i-1]+ wt[i-1];
29. }
30.
31. printf("Process ID Burst Time Waiting Time TurnAround Time\n");
32. float twt=0.0;
33. float tat= 0.0;
34. for(i=0; i<n; i++)
35. {
36. printf("%d\t\t", pid[i]);
37. printf("%d\t\t", bt[i]);
38. printf("%d\t\t", wt[i]);
39.
40. //calculating and printing turnaround time of each process
41. printf("%d\t\t", bt[i]+wt[i]);
42. printf("\n");
43.
44. //for calculating total waiting time
45. twt += wt[i];
46.
47. //for calculating total turnaround time
48. tat += (wt[i]+bt[i]);
49. }
50. float att,awt;
51.
52. //for calculating average waiting time
53. awt = twt/n;
54.
55. //for calculating average turnaround time
56. att = tat/n;
57. printf("Avg. waiting time= %f\n",awt);
58. printf("Avg. turnaround time= %f",att);
59. }

OUTPUT:
(EXP-1 : FCFS Scheduling)

EXPERIMENT – 2
AIM: C program to implement a round robin scheduling algorithm.

THEORY:
Round Robin Scheduling is a CPU scheduling algorithm in which each process is executed
for a fixed time slot. Since the resources are snatched after the time slot, round robin is pre-
emptive.
Pre-emptive: In this type, resources can be voluntarily snatched.
Non-Pre-emptive: In this type, if a process is once started, it will execute completely i.e
resources cannot be snatched.

Characteristics of Round Robin


1. It is a pre-emptive algorithm.
2. It shares an equal time interval between all processes to complete their task.
3. It is a starvation free CPU scheduling algorithm. Hence it is known as the fairest and
simple algorithm.

Following are the basic terminologies:

Turnaround Time: Difference between completion time and arrival time.


Turnaround Time = Completion Time – Arrival Time

Waiting Time: Time Difference between turnaround time and burst time.
Waiting Time = Turnaround Time – Burst Time

Round Robin Scheduling Algorithm:


Step 1: Start the Program.
Step 2: Input the number of processes.
Step 3: Input the burst time and arrival time of each process and the limit of the time slot.
Step 4: Push all processes into the ready queue according to their arrival time. Then execute
each process upto time slot and push left over process in queue again for execution.
Step 5: After a process is completely executed, print its turn around time and waiting time.

PROGRAM:

1. #include<stdio.h>
2. #include<conio.h>
3. void main()
4. {
5. // initlialize the variable name
6. int i, NOP, sum=0,count=0, y, quant, wt=0, tat=0, at[10], bt[10], temp[10];
7. float avg_wt, avg_tat;
8. printf(" Total number of process in the system: ");
9. scanf("%d", &NOP);
10. y = NOP; // Assign the number of process to variable y
11.
12. // Use for loop to enter the details of the process like Arrival time and the Burst Time
13. for(i=0; i<NOP; i++)
14. {
15. printf("\n Enter the Arrival and Burst time of the Process[%d]\n", i+1);
16. printf(" Arrival time is: \t"); // Accept arrival time
17. scanf("%d", &at[i]);
18. printf(" \nBurst time is: \t"); // Accept the Burst time
19. scanf("%d", &bt[i]);
20. temp[i] = bt[i]; // store the burst time in temp array
21. }
22. // Accept the Time qunat
23. printf("Enter the Time Quantum for the process: \t");
24. scanf("%d", &quant);
25. // Display the process No, burst time, Turn Around Time and the waiting time
26. printf("\n Process No \t\t Burst Time \t\t TAT \t\t Waiting Time ");
27. for(sum=0, i = 0; y!=0; )
28. {
29. if(temp[i] <= quant && temp[i] > 0) // define the conditions
30. {
31. sum = sum + temp[i];
32. temp[i] = 0;
33. count=1;
34. }
35. else if(temp[i] > 0)
36. {
37. temp[i] = temp[i] - quant;
38. sum = sum + quant;
39. }
40. if(temp[i]==0 && count==1)
41. {
42. y--; //decrement the process no.
43. printf("\nProcess No[%d] \t\t %d\t\t\t\t %d\t\t\t %d", i+1, bt[i], sum-at[i], sum-
at[i]-bt[i]);
44. wt = wt+sum-at[i]-bt[i];
45. tat = tat+sum-at[i];
46. count =0;
47. }
48. if(i==NOP-1)
49. {
50. i=0;
51. }
52. else if(at[i+1]<=sum)
53. {
54. i++;
55. }
56. else
57. {
58. i=0;
59. }
60. }
61. // represents the average waiting time and Turn Around time
62. avg_wt = wt * 1.0/NOP;
63. avg_tat = tat * 1.0/NOP;
64. printf("\n Average Turn Around Time: \t%f", avg_wt);
65. printf("\n Average Waiting Time: \t%f", avg_tat);
66. getch();
67. }

OUTPUT:
(EXP-2 : Round Robin Scheduling)
EXPERIMENT – 3
AIM: Implementation of the following Memory Allocation Methods for fixed partition
a) First Fit b) Worst Fit c) Best Fit.

THEORY:
1. First Fit: In the first fit, the partition is allocated which is the first sufficient block
from the top of Main Memory. It scans memory from the beginning and chooses the
first available block that is large enough. Thus it allocates the first hole that is large
enough.
2. Best Fit Allocate the process to the partition which is the first smallest sufficient
partition among the free available partition. It searches the entire list of holes to find
the smallest hole whose size is greater than or equal to the size of the process.
3. Worst Fit Allocate the process to the partition which is the largest sufficient among
the freely available partitions available in the main memory. It is opposite to the
best-fit algorithm. It searches the entire list of holes to find the largest hole and
allocate it to process.

FIRST FIT MEMORY ALLOCATION:


Implementation:
1. Input memory blocks with size and processes with size.
2. Initialize all memory blocks as free.
3. Start by picking each process and check if it can be assigned to current block.
4. If size-of-process <= size-of-block if yes then assign and check for next process.
5. If not then keep checking the further blocks.

Program:

// C implementation of First - Fit algorithm


#include<stdio.h>

// Function to allocate memory to


// blocks as per First fit algorithm
void firstFit(int blockSize[], int m, int processSize[], int n)
{
int i, j;
// Stores block id of the
// block allocated to a process
int allocation[n];

// Initially no block is assigned to any process


for(i = 0; i < n; i++)
{
allocation[i] = -1;
}

// pick each process and find suitable blocks


// according to its size ad assign to it
for (i = 0; i < n; i++) //here, n -> number of processes
{
for (j = 0; j < m; j++) //here, m -> number of blocks
{
if (blockSize[j] >= processSize[i])
{
// allocating block j to the ith process
allocation[i] = j;

// Reduce available memory in this block.


blockSize[j] -= processSize[i];

break; //go to the next process in the queue


}
}
}

printf("\nProcess No.\tProcess Size\tBlock no.\n");


for (int i = 0; i < n; i++)
{
printf(" %i\t\t\t", i+1);
printf("%i\t\t\t\t", processSize[i]);
if (allocation[i] != -1)
printf("%i", allocation[i] + 1);
else
printf("Not Allocated");
printf("\n");
}
}

// Driver code
int main()
{
int m; //number of blocks in the memory
int n; //number of processes in the input queue
int blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 417, 112, 426};
m = sizeof(blockSize) / sizeof(blockSize[0]);
n = sizeof(processSize) / sizeof(processSize[0]);

firstFit(blockSize, m, processSize, n);

return 0 ;
}

Output:
(EXP-3 : First Fit Memory Allocation)
WORST FIT MEMORY ALLOCATION:
Implementation:
1. Input memory blocks and processes with sizes.
2. Initialize all memory blocks as free.
3. Start by picking each process and find the maximum block size that can be assigned
to current process i.e.,
find max(bockSize[1], blockSize[2],.....blockSize[n]) > processSize[current], if
found then assign it to the current process.
4. If not then leave that process and keep checking
5. the further processes.

Program:
#include <stdio.h>
#include <stdlib.h>

void worstFit(int blockSize[], int m, int processSize[], int n) {


int *allocation = (int *)malloc(n * sizeof(int));
memset(allocation, -1, n * sizeof(int));

for (int i = 0; i < n; i++) {


int wstIdx = -1;
for (int j = 0; j < m; j++) {
if (blockSize[j] >= processSize[i]) {
if (wstIdx == -1)
wstIdx = j;
else if (blockSize[wstIdx] < blockSize[j])
wstIdx = j;
}
}

if (wstIdx != -1) {
allocation[i] = wstIdx;
blockSize[wstIdx] -= processSize[i];
}
}
printf("\nProcess No.\tProcess Size\tBlock no.\n");
for (int i = 0; i < n; i++) {
printf(" %d\t\t%d\t\t", i + 1, processSize[i]);
if (allocation[i] != -1)
printf("%d", allocation[i] + 1);
else
printf("Not Allocated");
printf("\n");
}

free(allocation);
}

int main() {
int blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 417};
int m = sizeof(blockSize) / sizeof(blockSize[0]);
int n = sizeof(processSize) / sizeof(processSize[0]);
worstFit(blockSize, m, processSize, n);
return 0;
}

Output:
(EXP-3 : Worst Fit Memory Allocation)

BEST FIT MEMORY ALLOCATION:


Implementation:
1. Input memory blocks and processes with sizes.
2. Initialize all memory blocks as free.
3. Start by picking each process and find the minimum block size that can be assigned
to current process i.e., find min(bockSize[1], blockSize[2],.....blockSize[n]) >
processSize[current], if found then assign it to the current process.
4. If not then leave that process and keep checking the further processes.

Program:

#include<stdio.h>

void bestFit(int blockSize[], int m, int processSize[], int n) {

int allocation[n];

for (int i = 0; i < n; i++)


allocation[i] = -1;

for (int i = 0; i < n; i++) {

int bestIdx = -1;


for (int j = 0; j < m; j++) {
if (blockSize[j] >= processSize[i]) {
if (bestIdx == -1)
bestIdx = j;
else if (blockSize[bestIdx] > blockSize[j])
bestIdx = j;
}
}

if (bestIdx != -1) {

allocation[i] = bestIdx;

blockSize[bestIdx] -= processSize[i];
}
}
printf("\nProcess No.\tProcess Size\tBlock no.\n");
for (int i = 0; i < n; i++) {
printf(" %d\t\t%d\t\t", i+1, processSize[i]);
if (allocation[i] != -1)
printf("%d", allocation[i] + 1);
else
printf("Not Allocated");
printf("\n");
}
}
int main() {
int blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 417, 112, 42};
int m = sizeof(blockSize) / sizeof(blockSize[0]);
int n = sizeof(processSize) / sizeof(processSize[0]);
bestFit(blockSize, m, processSize, n);
return 0;
}

Output:
(EXP-3 : Best Fit Memory Allocation)

EXPERIMENT – 4
AIM: Write a program to implement reader/writer problems using semaphores.
THEORY:
The reader/writer problem is a classic synchronization problem. It deals with concurrent
access to shared resources where multiple processes are involved. The problem can be
defined as follows:
- Multiple readers can simultaneously access a shared resource without any problems.
- Only one writer can access the resource at a time, and no readers can access the resource
while a writer is writing.
Algorithm:
Initialization:
- Initialize the `mutex` semaphore to 1.
- Initialize the `write` semaphore to 1.
- Initialize `read_count` to 0.
Reader Process:
1. Wait on `mutex`.
2. Increment `read_count`.
3. If `read_count` is 1, wait on `write` to prevent writers.
4. Signal `mutex`.
5. Read the data from the shared resource.
6. Wait on `mutex`.
7. Decrement `read_count`.
8. If `read_count` is 0, signal `write` to allow writers.
9. Signal `mutex`.
Writer Process:
1. Wait on `write` to ensure exclusive access for writing.
2. Write data to the shared resource.
3. Signal `write` to release the resource.

PROGRAM
#include <stdio.h>
#include <pthread.h>
int readcount = 0, writecount = 0, sh_var = 5, bsize[5];
pthread_mutex_t x, y, z;
pthread_cond_t rsem, wsem;
void *reader(void *);
void *writer(void *);
void *reader(void *i)
{
printf("\n-------------------------");
printf("\n\n reader-%ld is reading", (long)i);
pthread_mutex_lock(&z);
pthread_mutex_lock(&rsem);
pthread_mutex_lock(&x);
readcount++;
if (readcount == 1)
pthread_mutex_lock(&wsem);
pthread_mutex_unlock(&x);
pthread_mutex_unlock(&rsem);
pthread_mutex_unlock(&z);
printf("\nupdated value: %d", sh_var);
pthread_mutex_lock(&x);
readcount--;
if (readcount == 0)
pthread_mutex_unlock(&wsem);
pthread_mutex_unlock(&x);
}

void *writer(void *i)


{
printf("\n\n writer-%ld is writing", (long)i);
pthread_mutex_lock(&y);
writecount++;
if (writecount == 1)
pthread_mutex_lock(&rsem);
pthread_mutex_unlock(&y);
pthread_mutex_lock(&wsem);
sh_var = sh_var + 5;
pthread_mutex_unlock(&wsem);
pthread_mutex_lock(&y);
writecount--;
if (writecount == 0)
pthread_mutex_unlock(&rsem);
pthread_mutex_unlock(&y);
}
int main()
{
pthread_mutex_init(&x, NULL);
pthread_mutex_init(&y, NULL);
pthread_mutex_init(&z, NULL);
pthread_cond_init(&rsem, NULL);
pthread_cond_init(&wsem, NULL);

pthread_t r[3], w[2];


for (long i = 0; i < 3; i++)
{
pthread_create(&r[i], NULL, reader, (void *)i);
}
for (long i = 0; i < 2; i++)
{
pthread_create(&w[i], NULL, writer, (void *)i);
}

pthread_exit(NULL);
}

OUTPUT:
(EXP-4 : reader/writer problems using semaphores.)
EXPERIMENT – 5
AIM: Write a program to implement Banker’s algorithm for deadlock avoidance.
THEORY:
The banker’s algorithm is a resource allocation and deadlock avoidance algorithm that tests
for safety by simulating the allocation for the predetermined maximum possible amounts of
all resources, then makes an “s-state” check to test for possible activities, before deciding
whether allocation should be allowed to continue.
Banker’s Algorithm
1. Active:= Running U Blocked;
for k=1…r
New_ request[k]:= Requested_ resources[requesting_ process, k];
2. Simulated_ allocation:= Allocated_ resources;
for k=1…..r //Compute projected allocation state
Simulated_ allocation [requesting _process, k]:= Simulated_ allocation [requesting
_process, k] + New_ request[k];
3. feasible:= true;
for k=1….r // Check whether projected allocation state is feasible
if Total_ resources[k]< Simulated_ total_ alloc [k] then feasible:= false;
4. if feasible= true
then // Check whether projected allocation state is a safe allocation state
while set Active contains a process P1 such that
For all k, Total _resources[k] – Simulated_ total_ alloc[k]>= Max_ need [l ,k]-
Simulated_ allocation[l, k]
Delete Pl from Active;
for k=1…..r
Simulated_ total_ alloc[k]:= Simulated_ total_ alloc[k]- Simulated_ allocation[l, k];
5. If set Active is empty
then // Projected allocation state is a safe allocation state
for k=1….r // Delete the request from pending requests
Requested_ resources[requesting_ process, k]:=0;
for k=1….r // Grant the request
Allocated_ resources[requesting_ process, k]:= Allocated_ resources[requesting_
process, k] + New_ request[k];
Total_ alloc[k]:= Total_ alloc[k] + New_ request[k];

PROGRAM:
// Banker's Algorithm
#include <stdio.h>
int main()
{
// P0, P1, P2, P3, P4 are the Process names here

int n, m, i, j, k;
n = 5; // Number of processes
m = 3; // Number of resources
int alloc[5][3] = { { 0, 1, 0 }, // P0 // Allocation Matrix
{ 2, 0, 0 }, // P1
{ 3, 0, 2 }, // P2
{ 2, 1, 1 }, // P3
{ 0, 0, 2 } }; // P4
int max[5][3] = { { 7, 5, 3 }, // P0 // MAX Matrix
{ 3, 2, 2 }, // P1
{ 9, 0, 2 }, // P2
{ 2, 2, 2 }, // P3
{ 4, 3, 3 } }; // P4
int avail[3] = { 3, 3, 2 }; // Available Resources
int f[n], ans[n], ind = 0;
for (k = 0; k < n; k++) {
f[k] = 0;
}
int need[n][m];
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++)
need[i][j] = max[i][j] - alloc[i][j];
}
int y = 0;
for (k = 0; k < 5; k++) {
for (i = 0; i < n; i++) {
if (f[i] == 0) {
int flag = 0;
for (j = 0; j < m; j++) {
if (need[i][j] > avail[j]){
flag = 1;
break;
}
}

if (flag == 0) {
ans[ind++] = i;
for (y = 0; y < m; y++)
avail[y] += alloc[i][y];
f[i] = 1;
}
}
}
}

int flag = 1;

for(int i=0;i<n;i++)
{
if(f[i]==0)
{
flag=0;
printf("The following system is not safe");
break;
}
}
if(flag==1)
{
printf("Following is the SAFE Sequence\n");
for (i = 0; i < n - 1; i++)
printf(" P%d ->", ans[i]);
printf(" P%d", ans[n - 1]);
}

return (0);

// This code is contributed by Deep Baldha (CandyZack)


}

OUTPUT:
(EXP-5 : Banker’s algorithm)
EXPERIMENT – 6
AIM: To study of basic UNIX commands and various UNIX editors such as vi, ed, ex and
EMACS

THEORY:
UNIX is a powerful and widely used operating system known for its command-line interface.
To work effectively in a UNIX environment, it is essential to be familiar with basic UNIX
commands and text editors.

Basic UNIX Commands:


1. `ls` (List Files): This command lists the files and directories in the current directory.
Example:
$ ls
file1.txt file2.txt directory1 directory2

2. `cd` (Change Directory): It is used to navigate between directories.


Example:
$ cd directory1

3. `mkdir` (Make Directory): This command creates a new directory.


Example:
$ mkdir new_directory

4. `rm` (Remove): It's used to remove files or directories.


Example:
$ rm file1.txt

5. `cp` (Copy): Copies files or directories from one location to another.


Example:
$ cp file2.txt new_directory/
6. `mv` (Move/Rename): Moves or renames files or directories.
Example (renaming):
$ mv file2.txt new_name.txt
7. `cat` (Concatenate and Display): It displays the contents of a file.
Example:
$ cat new_name.txt
This is the content of the file.

8. `man` (Manual Pages): It displays the manual or documentation for a command.


Example:
$ man ls

UNIX EDITORS:
1. vi:
- Vi is a terminal-based text editor with different modes (normal, insert, and command
mode).
- To open a file in vi: `$ vi filename`
- In normal mode, to insert text, press `i`. To save and exit, press `Esc`, then `:wq`.
Example: Open a file in vi, add text, save, and exit.
$ vi sample.txt
# Press 'i' to enter insert mode and add text.
This is a vi example.
# Press 'Esc' to exit insert mode.
# Enter ':wq' to save and exit.

2. ed:
- Ed is a line-oriented text editor often used for scripting and automation.
- Example: Create a file using ed.
$ ed newfile.txt
a
This is text added using ed.
.
w
q
3. ex:
- Ex is an extended version of ed with a more user-friendly interface.
- Example: Edit a file using ex.
$ ex existingfile.txt
i
This is new text added using ex.
.
w
q

4. EMACS:
- EMACS is a highly extensible text editor with numerous features.
- To open a file in EMACS: `$ emacs filename`
- For basic editing, type text and save with `Ctrl-X Ctrl-S`. To exit, use `Ctrl-X Ctrl-C`.

Example: Open a file in EMACS, add text, save, and exit.


$ emacs sample.txt
# Type text.
This is an EMACS example.
# Save with 'Ctrl-X Ctrl-S' and exit with 'Ctrl-X Ctrl-C'.

EXPERIMENT – 7

AIM: Process Management


a) Program to implement the fork function using C.
b) Program to implement execv function using C.
c) Program to implement execlp function.
d) Program to implement wait function using C.
e) Program to implement sleep function using C.

THEORY:
Fork():
 The `fork()` function creates a new process, known as a child process, which is a copy
of the current process (parent).
 The child process starts execution from the point where `fork()` was called.
 Both the parent and child processes have their own memory space, CPU registers, and
file descriptors.
execv():
 The `execv()` function is used to replace the current process image with a new
program.
 It loads and runs a new program by specifying its path and command-line arguments.
 The old program's code, data, and stack segments are replaced by the new program.
execlp():
 `execlp()` is another function to execute a new program, but it searches for the
program in directories listed in the `PATH` environment variable.
 This means you only need to specify the program's name without its full path.
wait():
 The `wait()` function is used for process synchronization, specifically to wait for child
processes to terminate.
 It allows the parent process to block until a child process exits, at which point it can
collect information about the child's exit status.
sleep():
 The `sleep()` function introduces a time delay in the execution of a program.
 It pauses the program for a specified number of seconds, allowing other processes to
execute.

To implement the fork function using C.


PROGRAM:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{

// make two process which run same


// program after this instruction
pid_t p = fork();
if(p<0){
perror("fork fail");
exit(1);
}
printf("Hello world!, process_id(pid) = %d \n",getpid());
return 0;
}

OUTPUT:

To implement execv function using C.


PROGRAM:
// child process
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
printf ("I am the child process");
printf ("Argument 1: %s\n", argv[1]);
printf ("Argument 2: %s\n", argv[2]);
printf ("Argument 3: %s\n", argv[3]);
}
// parent process
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main (){
printf ("\n\nI am the parent process\n");
char *arg_Ptr[5];
arg_Ptr[0] = " child.c";
arg_Ptr[1] = " \nHello from ";
arg_Ptr[2] = " process 2 ";
arg_Ptr[3] = NULL;
execv("/home/linuxhint/child.bin", arg_Ptr);
}

OUTPUT:
To implement execlp function

PROGRAM:
1. #include <unistd.h>
2. #include <stdio.h>
3.
4. int main() {
5. printf("Executing ls command...\n");
6. execlp("ls", "ls", "-l", NULL);
7. return 0;
8. }

OUTPUT:

To implement wait function using C

PROGRAM:
OUTPUT:

To implement sleep function using C

PROGRAM:
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main()
{
int sleep_seconds = 5;
printf("Calling the sleep function for %d seconds\n", sleep_seconds);
printf("Timestamp: %d\n",(int)time(NULL));
sleep(sleep_seconds);
printf("Timestamp: %d\n",(int)time(NULL));
return 0;
}

OUTPUT:
EXPERIMENT – 8

AIM: To write simple shell programs by using conditional, branching and looping statements
Conditional Statements: There are total 5 conditional statements which can be used in
bash programming
1. if statement
This block will process if specified condition is true.
Syntax:
if [ expression ]
then
statement
fi

2. if-else statement
If specified condition is not true in if part then else part will be execute.
Syntax
if [ expression ]
then
statement1
else
statement2
fi

3. if..elif..else..fi statement (Else If ladder)


To use multiple conditions in one if-else block, then elif keyword is used in shell.
Syntax
if [ expression1 ]
then
statement1
Statement2
elif [ expression2 ]
then
statement3
statement4
else
statement5
fi
4. if..then..else..if..then..fi..fi..(Nested if)
Nested if-else block can be used when, one condition is satisfies then it again checks another
condition. In the syntax, if expression1 is false then it processes else part, and again
expression2 will be check.
Syntax:if [ expression1 ]
then
statement1

else
if [ expression2 ]
then
statement3
……
fi
fi

5. switch statement
Syntax:
case in
Pattern 1) Statement 1;;
Pattern n) Statement n;;
esac

Looping Statements in Shell Scripting: There are total 3 looping statements that can be
used in bash programming
1. while statement
while <condition>
do
<command 1>

done

2. for statement
The for loop operates on lists of items. It repeats a set of commands for every item in a list.
for <var> in <value1 value2 ... valuen>
do
<command 1>

done
3. until statement
until <condition>
do
<command 1>

done
Branching statements:
Branching statements allow the flow of execution to jump to a different part of the program.
The common branching statements used within other control structures
include: break, continue, return, and goto. The goto is rarely used in modular structured
programming. Additionally, we will add to our list of branching items a pre-defined function
commonly used in programming languages of: exit.

PROGRAM:
Program 8.1

Output

Program8.2

Output
Program 8.3

Output:

Program 8.4
#for loop and break
Program8.5
#While loop

Program8.6
#Until
EXPERIMENT – 9

AIM: Write a Shell Program to swap two integers.


THEORY:
A shell is a command-line interpreter and typical operations performed by shell scripts
include file manipulation, program execution, and printing text.
Approach:
1. Store the value of the first number into a temp variable.
2. Store the value of the second number in the first number.
3. Store the value of temp into the second variable.

PROGRAM:

OUTPUT:

You might also like