Lab No.
01
Course Name: Programming Techniques
Submitted by: Rabia Sarfraz
Roll No.: 2330-0070
Class Section: FA23/BS(SE)
Submitted to: Ma’am Aymen Fatima
DATE: 23rd February,25
Basic Commands:
Ls
This command is used to list directory contents.
Ls –l
This command displays a detailed list of files and directories in the
current directory.
It shows
Detailed info
Check the last modified date
File ownership
File size
Check permissions
Ls –a
This command is used to show all the files including hidden ones.
Sudo apt Update
This command is used to update the package lists for available software
updates.
Sudo apt Upgrade
This command is used to install all the updates available.
Mkdir
This command is used to create a new directory.
Full-Form: Make Directory
Touch
This command is used to create a new file.
Pwd
This command prints the current working directory.
Full-Form: Print Working Directory
Cd
This command is used to change the current working directory.
Cd folder_name = moves to folder_name (directory changes).
Full-Form: Change Directory
Cd ..
This command is used to take you to the previous directory.
Cd /
This command is used to take you to the main root directory.
History
This command is used to show history, i.e. all the commands that were
run previously.
Whoami
This command is used to show the user name.
Full-Form: Who Am I
Df –h
This command is used to view disk usage.
Clear
This command is used to clear the terminal.
Rmdir
This command is used to remove the directory.
Full-Form: Remover Directory
Rm
This command is used to remove files.
Cp
This command is used to copy files.
Exit
This command is used to exit the terminal.
Task # 01:
Create the following directory structure:
Solution:
Task # 02:
Write a program that prints odd numbers from 1 to 10 and prints their sum,
compile and run it using gcc.
Solution:
Code:
#include<stdio.h>
int main()
{
int i, sum;
for(i=1;i<=10;i++)
{
if(i%2!=0)
{
printf("%d\n",i);
sum+=i;
}
}
printf("Sum of odd numbers is %d",sum);
return 0;
}
Task # 03:
Student Grade Calculation System
Create a C program that calculates a student's average grade based on
multiple subjects, determines the corresponding letter grade, and displays the
results. You will implement this using functions to promote code reuse and
organization.
Solution:
Code:
#include <stdio.h>
#define num_subjectS 5
// Function prototypes
void inputMarks(float marks[], int numSubjects);
float calculateavg(float marks[], int numSubjects);
char determineGrade(float average);
void displayResults(float marks[], int numSubjects, float average, char grade);
int main() {
float marks[num_subjectS];
float avg;
char grade;
// Input marks
inputMarks(marks, num_subjectS);
// Calculate average
avg = calculateavg(marks, num_subjectS);
// Determine letter grade
grade = determineGrade(avg);
// Display results
displayResults(marks, num_subjectS, avg, grade);
return 0;
}
void inputMarks(float marks[], int numSubjects) {
for (int i = 0; i < numSubjects; i++) {
printf("Enter marks for subject %d: ", i + 1);
scanf("%f", &marks[i]);
}
}
float calculateavg(float marks[], int numSubjects) {
float sum = 0.0;
for (int i = 0; i < numSubjects; i++) {
sum += marks[i];
}
return sum / numSubjects;
}
char determineGrade(float avg) {
if (avg >= 80) {
return 'A';
} else if (avg >= 70) {
return 'B';
} else if (avg >= 60) {
return 'C';
} else if (avg >= 50) {
return 'D';
} else {
return 'F';
}
}
void displayResults(float marks[], int numSubjects, float avg, char grade) {
printf("\nmarks:\n");
for (int i = 0; i < numSubjects; i++) {
printf("Subject %d: %.2f\n", i + 1, marks[i]);
}
printf("avg: %.2f\n", avg);
printf("marks: %c\n", grade);
}
The end!
Lab No. 03
Course Name: Operating System
Submitted by: Rabia Sarfraz
Roll No.: 2330-0070
Class Section: FA23/BS(SE)
Submitted to: Ma’am Aymen
DATE: 5th March, 2025
Task No. 01:
Write a program that accepts a number through CLI and generates the Fibonacci
series in the child process.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void generateFibonacci(int n)
{
int a = 0, b = 1, next;
printf("Fibonacci Series: ");
for (int i = 0; i < n; i++)
{
printf("%d ", a);
next = a + b;
a = b;
b = next;
}
printf("\n");
}
int main(int argc, char* argv[])
{
if (argc != 2)
{
printf("Usage: %s <number>\n", argv[0]);
return 1;
}
int n = atoi(argv[1]); // Convert input argument to integer
if (n <= 0)
{
printf("Please enter a positive integer.\n");
return 1;
}
pid_t pid = fork(); // Create child process
if (pid<0)
{
printf("Fork failed!\n");
return 1;
}
else if (pid == 0)
{
// Child Process
printf("Child Process (PID: %d) Generating Fibonacci Series...\n", getpid());
generateFibonacci(n);
}
else
{
// Parent Process
wait(NULL); // Wait for child process to finish
printf("Parent Process (PID: %d) Execution Completed.\n", getpid());
}
return 0;
}
Output:
Task No. 02:
Modify program 1 to accept more than 1 number by CLI. Like
./myFabonacciSeries 10 12 7
Your program should spawn a new child process for each number to generate its
Fibonacci series.
Code:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
void generateFibonacci(int n)
{
int a=0,b=1,next;
printf("Fibonacci Series for %d: ", n);
for(int i=0;i<n;i++)
{
printf("%d ",a);
next=a+b;
a=b;
b=next;
}
printf("\n");
}
int main(int argc, char* argv[])
{
if(argc<2)
{
printf("usage: %s <number>\n", argv[0]);
return 1;
}
for(int i=1; i<argc;i++)
{
int n=atoi(argv[i]);
if(n<=0)
{
printf("please enter a positive integer. \n");
continue;
}
pid_t pid=fork();
if(pid<0)
{
printf("Fork failed!\n");
return 1;
}
else if(pid==0)
{
//child process
printf("Child process (PID: %d) Generating Fibonacci Series.......\n", getpid());
generateFibonacci(n);
exit(0); //ensure child is terminated.
}
}
//parent process
while(wait(NULL)>0);
printf("Parent Process (PID: %d) Execution Completed.\n", getpid());
return 0;
}
Output:
Task No. 3:
How can you use a fork() in a for loop to create multiple child processes?
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
int numChildren = 3; // Number of child processes to create
for (int i = 0; i < numChildren; i++)
{
pid_t pid = fork(); // Create a child process
if (pid < 0)
{
// Fork failed
printf("Fork failed at iteration %d\n", i);
return 1;
}
else if (pid == 0) {
// Child process
printf("Child %d (PID: %d) created by parent (PID: %d)\n", i, getpid(),
getppid());
exit(0); // Ensure child process exits to prevent unwanted behavior
}
}
// Parent process waits for all children to complete
while (wait(NULL) > 0);
printf("Parent process (PID: %d) execution completed.\n", getpid());
return 0;
}
Output:
Task No. 4:
Write a C program that demonstrates process creation using the fork() system call.
The program should create a child process from the parent process and perform the
following tasks:
1. The parent process should print its Process ID (PID) and the PID of its child.
2. The child process should print its own PID and its parent's PID.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
pid_t pid = fork(); // Create a new process
if (pid < 0)
{
// Fork failed
printf("Fork failed!\n");
return 1;
}
else if (pid == 0)
{
// Child process
printf("Child Process:\n");
printf(" PID: %d\n", getpid()); // Get child process ID
printf(" Parent PID: %d\n", getppid()); // Get parent process ID
}
else
{
// Parent process
printf("Parent Process:\n");
printf(" PID: %d\n", getpid()); // Get parent process ID
printf(" Child PID: %d\n", pid); // Get child process ID
}
return 0;
}
Output:
Task No. 5:
Write a C program using the fork() system call to perform basic math operations.
The program should create a child process and perform the following tasks:
1. The parent process should calculate the sum of two numbers and print the result.
2. The child process should calculate the product of two numbers and print the
result.
3. The parent process should wait for the child process to complete before printing
"Math operations completed."
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
int num1 = 10, num2 = 5; // Numbers for operations
pid_t pid = fork(); // Create a new child process
if (pid < 0)
{
// Fork failed
printf("Fork failed!\n");
return 1;
}
else if (pid == 0)
{
// Child process: Calculate the product
printf("Child Process (PID: %d):\n", getpid());
printf(" Product of %d and %d = %d\n", num1, num2, num1 * num2);
exit(0); // Child exits after task completion
}
else
{
// Parent process: Calculate the sum
wait(NULL); // Wait for the child process to complete
printf("Parent Process (PID: %d):\n", getpid());
printf(" Sum of %d and %d = %d\n", num1, num2, num1 + num2);
printf("Math operations completed.\n");
}
return 0;
}
Output:
The end!
Lab No. 04
Course Name: Operating System
Submitted by: Rabia Sarfraz
Roll No.: 2330-0070
Class Section: FA23/BS(SE)
Submitted to: Ma’am Aymen
DATE: 11th March, 2025
Task No. 01:
Write a program where the child process sends an integer number to the parent
process using an unnamed pipe. The parent process reads the number from the pipe
and prints it.
Code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
int pipefd[2]; // File descriptors for the pipe
pid_t pid;
if(pipe(pipefd)==-1)
{
printf("pipe failed");
return 1;
}
pid = fork();
if(pid<0)
{
printf("fork failed");
return 1;
}
if (pid==0)
{ // Child process
close(pipefd[0]); // Close unused read end
int num=42; //number to send
write(pipefd[1], &num, sizeof(num)); // Write number to pipe
close(pipefd[1]); // Close write end
}
else
{ // Parent process
close(pipefd[1]); // Close unused write end
int received_num;
read(pipefd[0], &received_num, sizeof(received_num)); // Read number from
pipe
printf("Parent received number: %d\n", received_num);
close(pipefd[0]); // Close read end
}
return 0;
}
Output:
Task No. 02:
Write a program where the parent process sends two integers to the child process
using an unnamed pipe. The child process reads the two numbers, calculates their
sum, and prints the result.
Code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
int pipefd[2]; // File descriptors for the pipe
pid_t pid;
if (pipe(pipefd) == -1)
{
printf("pipe failed");
return 1;
}
pid=fork();
if (pid<0)
{
printf("fork failed");
return 1;
}
if(pid>0)
{
// Parent process
close(pipefd[0]); // Close unused read end
int num1 = 15, num2 = 27; // Numbers to send
write(pipefd[1], &num1, sizeof(num1)); // Write first number to pipe
write(pipefd[1], &num2, sizeof(num2)); // Write second number to pipe
close(pipefd[1]); // Close write end
}
else
{
// Child process
close(pipefd[1]); // Close unused write end
int received_num1, received_num2;
read(pipefd[0], &received_num1, sizeof(received_num1)); // Read first
number from pipe
read(pipefd[0], &received_num2, sizeof(received_num2)); // Read second
number from pipe
printf("Child received numbers: %d and %d\n", received_num1,
received_num2);
printf("Sum: %d\n", received_num1 + received_num2);
close(pipefd[0]); // Close read end
}
return 0;
}
Output:
Task No. 03:
Write a program to calculate factorial of a number. Following constraints must be
fulfilled:
• Use pipe to solve your problem.
• Child process should send number for factorial to parent.
• Parent process is responsible to calculate the factorial.
• parent process should print the final result.
HINT: use atoi () build in function.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
// Function to calculate factorial
unsigned long long factorial(int n)
{
if(n==0||n==1)
return 1;
return n*factorial(n-1);
}
int main()
{
int fd[2]; // File descriptors for pipe
pid_t pid;
if(pipe(fd)==-1)
{
printf("Pipe failed");
return 1;
}
pid=fork();
if(pid<0)
{
printf("Fork failed");
return 1;
}
if (pid == 0)
{
// Child process
close(fd[0]); // Close reading end of pipe
int num;
printf("Enter a number: ");
scanf("%d", &num);
write(fd[1], &num, sizeof(num)); // Write number to pipe
close(fd[1]); // Close writing end of pipe
}
else
{
// Parent process
close(fd[1]); // Close writing end of pipe
int received_num;
read(fd[0], &received_num, sizeof(received_num)); // Read number from pipe
close(fd[0]); // Close reading end of pipe
// Calculate factorial
unsigned long long result = factorial(received_num);
// Print result
printf("Factorial of %d is %llu\n", received_num, result);
}
return 0;
}
Output:
Task No. 04:
Write a program that counts number of vowels in a string. Following constraints
must be fulfilled:
• Use pipe to solve your problem.
• Child process should send string to parent.
• Parent process is responsible to count the vowels and also print the final answer.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <ctype.h> // Include ctype.h for tolower()
// Function to count vowels in a string
int count_vowels(const char *str)
{
int count = 0;
for (int i = 0; str[i] != '\0'; i++)
{
char ch = tolower(str[i]);
if(ch=='a'||ch=='e'||ch=='i'||ch == 'o'||ch=='u')
{
count++;
}
}
return count;
}
int main()
{
int fd[2]; // File descriptors for pipe
pid_t pid;
if(pipe(fd)==-1)
{
printf("Pipe failed");
return 1;
}
pid=fork();
if(pid<0)
{
printf("Fork failed");
return 1;
}
if(pid==0)
{
// Child process
close(fd[0]); // Close reading end of pipe
char input_str[100];
printf("Enter a string: ");
fgets(input_str, sizeof(input_str), stdin);
input_str[strcspn(input_str, "\n")] = 0; // Remove newline character
write(fd[1], input_str, strlen(input_str) + 1); // Write string to pipe
close(fd[1]); // Close writing end of pipe
}
else
{
// Parent process
close(fd[1]); // Close writing end of pipe
char received_str[100];
read(fd[0], received_str, sizeof(received_str)); // Read string from pipe
close(fd[0]); // Close reading end of pipe
// Count vowels
int vowel_count = count_vowels(received_str);
// Print result
printf("Number of vowels in the string: %d\n", vowel_count);
}
return 0;
}
Output:
Lab No. 6
Course Name: Operating System
Submitted by: Rabia Sarfraz
Roll No.: 2330-0070
Class Section: FA23/BS(SE)
Submitted to: Ma’am Aymen Fatima
DATE: 24th March, 2025
Task No. 01:
Implement a Bounded Buffer with a Fixed Number of Items.
Modify the above example code so that:
1. The producer only produces a fixed number of items, say 8, and then stops.
2. The consumer will consume these 8 items and then stop.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define BUFFER_SIZE 5 // Define buffer size
int buffer[BUFFER_SIZE]; // Shared buffer
int in = 0; // Producer index in buffer
int out = 0; // Consumer index in buffer
int count = 0; // Count of items in buffer
// Producer function
void* producer(void* arg) {
int itemP;
for(int i=0;i<8;i++)
{
itemP = rand() % 100; // Produce a random item
// Wait if buffer is full
while (count == BUFFER_SIZE) {
// Busy wait
}
// Produce an item in the buffer
buffer[in] = itemP;
printf("Producer produced: %d\n", itemP);
in = (in + 1) % BUFFER_SIZE; // Move to next position
count++; // Increment count of items in buffer
sleep(1); // Simulate time taken to produce
}
}
// Consumer function
void* consumer(void* arg) {
int itemC;
for(int i=0;i<8;i++)
{
// Wait if buffer is empty
while (count == 0) {
// Busy wait
}
// Consume an item from the buffer
itemC = buffer[out];
printf("Consumer consumed: %d\n", itemC);
out = (out + 1) % BUFFER_SIZE; // Move to next position
count--; // Decrement count of items in buffer
sleep(1); // Simulate time taken to consume
}
}
int main() {
pthread_t prodThread, consThread;
// Create producer and consumer threads
pthread_create(&prodThread, NULL, producer, NULL);
pthread_create(&consThread, NULL, consumer, NULL);
// Wait for both threads to finish (they run indefinitely here)
pthread_join(prodThread, NULL);
pthread_join(consThread, NULL);
return 0;
}
Output:
Task No. 02:
Implement Delays for the Producer and Consumer to Simulate Realistic
Production and Consumption Rates.
Add variable delays to the producer and consumer functions to simulate real-world
scenarios where the producer may produce items faster or slower than the
consumer can consume them, and vice versa. Observe how the buffer fills up and
empties with different production and consumption rates.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define BUFFER_SIZE 5
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
int count = 0;
// Producer function
void* producer(void* arg) {
int itemP;
for(int i=0;i<8;i++)
{
itemP = rand() % 100; // Produce a random item
// Wait if buffer is full
while (count == BUFFER_SIZE)
{
// Busy wait
}
// Produce an item in the buffer
buffer[in] = itemP;
printf("Producer produced: %d\n", itemP);
in = (in + 1) % BUFFER_SIZE; // Move to next position
count++; // Increment count of items in buffer
sleep(rand()%3); // Simulate time randomly taken to produce
}
}
// Consumer function
void* consumer(void* arg)
{
int itemC;
for(int i=0;i<8;i++)
{
// Wait if buffer is empty
while (count == 0)
{
// Busy wait
}
// Consume an item from the buffer
itemC = buffer[out];
printf("Consumer consumed: %d\n", itemC);
out = (out + 1) % BUFFER_SIZE; // Move to next position
count--; // Decrement count of items in buffer
sleep(rand()%3); // Simulate time randomly taken to consume
}
}
int main()
{
pthread_t prodThread, consThread;
// Create producer and consumer threads
pthread_create(&prodThread, NULL, producer, NULL);
pthread_create(&consThread, NULL, consumer, NULL);
// Wait for both threads to finish (they run indefinitely here)
pthread_join(prodThread, NULL);
pthread_join(consThread, NULL);
return 0;
}
Output:
Task No. 03:
Write a program that initiate two threads, producer and consumer. Producer should
produce random numbers using rand( ) function between 0 and 10. It must block
indefinitely if circular queue is full. Consumer thread will read numbers from
queue and determine that each number is even or odd-number or not.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define BUFFER_SIZE 5 // Define buffer size
int buffer[BUFFER_SIZE]; // Shared buffer
int in = 0;
int out = 0;
int count = 0;
// Producer function
void* producer(void* arg) {
int itemP;
for(int i=0;i<8;i++)
{
itemP = rand() % 10; // Produce a random item
// Wait if buffer is full
while (count == BUFFER_SIZE)
{
// Busy wait
}
// Produce an item in the buffer
buffer[in] = itemP;
printf("Producer produced: %d\n", itemP);
in = (in + 1) % BUFFER_SIZE; // Move to next position
count++; // Increment count of items in buffer
sleep(1); // Simulate time taken to produce
}
}
// Consumer function
void* consumer(void* arg)
{
int itemC;
for(int i=0;i<8;i++)
{
// Wait if buffer is empty
while (count == 0)
{
// Busy wait
}
// Consume an item from the buffer
itemC = buffer[out];
if(buffer[out]%2==0)
{
printf("Data comming is even.\n");
printf("Consumer consumed: %d\n", itemC);
printf("\n");
}
else
{
printf("Data comming is odd.\n");
printf("Consumer consumed: %d\n", itemC);
printf("\n");
}
out = (out + 1) % BUFFER_SIZE; // Move to next position
count--; // Decrement count of items in buffer
sleep(1); // Simulate time taken to consume
}
}
int main()
{
pthread_t prodThread, consThread;
// Create producer and consumer threads
pthread_create(&prodThread, NULL, producer, NULL);
pthread_create(&consThread, NULL, consumer, NULL);
// Wait for both threads to finish (they run indefinitely here)
pthread_join(prodThread, NULL);
pthread_join(consThread, NULL);
return 0;
}
Output:
The End!