Uploaded by Aizan Malik

BSE4B LabTerminal SP23

advertisement
1
COMSATS UNIVERSITY ISLAMABAD
OPERATING SYSTEMS
LAB TERMINAL PROJECT
Submitted by
ABDUL REHMAN KHAN (SP21-BSE-002)
ABU BAKAR (SP21-BSE-005)
Class
BSE-4B
Submitted to
MAM HAFIZA SUNDUS
Date of Submission
8th June, 2023
2
Q1: Write a program (in C/C++ only) to implement the following scheme:
A process first creates an empty array of size 10. It then creates two threads. Each
thread takes input from user and places it in array. First thread is responsible of taking
5 inputs (one by one) from user and placing it in upper half of that array and second
thread does the same for the lower half of the array. Both threads run parallel so they
should be synchronized while accessing the shared array. The main process should
wait for these two threads. After both threads are executed, the main process should
add the array entries for each thread and display the number count for each thread.
The output should look like:
Array:
3
5
1
0
6
7
1
2
9
1
Thread 1 count: 15
Thread 2 count: 20
Solution:
In this program, we use the mutex to ensure that both threads access the shared array in a
synchronized manner. The first thread (inputThread1) takes input from the user and stores it in the
upper half of the array, updating the thread1Count variable accordingly. Similarly, the second thread
(inputThread2) takes input from the user and stores it in the lower half of the array, updating the
thread2Count variable.
After both threads have finished executing, the main process displays the contents of the array and
the count for each thread.
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
const int ARRAY_SIZE = 10;
int sharedArray[ARRAY_SIZE]; // Shared array
mutex mtx; // Mutex for protecting shared resources
int thread1Count = 0; // Counter for Thread 1
3
int thread2Count = 0; // Counter for Thread 2
void inputThread1() {
lock_guard<mutex> lock(mtx); // Lock the mutex
cout << "Enter 5 integers for Thread 1: ";
for (int i = 0; i < ARRAY_SIZE / 2; i++) {
cin >> sharedArray[i]; // Read input for Thread 1 and store in shared array
thread1Count += sharedArray[i]; // Update the count for Thread 1
}
}
void inputThread2() {
lock_guard<mutex> lock(mtx); // Lock the mutex
cout << "Enter 5 integers for Thread 2: ";
for (int i = ARRAY_SIZE / 2; i < ARRAY_SIZE; i++) {
cin >> sharedArray[i]; // Read input for Thread 2 and store in shared array
thread2Count += sharedArray[i]; // Update the count for Thread 2
}
}
int main() {
thread t2(inputThread2); // Create Thread 1
thread t1(inputThread1); // Create Thread 2
t2.join(); // Wait for Thread 2 to finish
t1.join(); // Wait for Thread 1 to finish
cout << "Array: ";
4
for (int i = 0; i < ARRAY_SIZE; i++) {
cout << sharedArray[i] << "\t"; // Print the elements of the shared array
}
cout << endl;
cout << "Thread 1 count: " << thread1Count << endl; // Print the count for Thread 1
cout << "Thread 2 count: " << thread2Count << endl; // Print the count for Thread 2
return 0;
}
OUTPUT:
Q2: Write a C/C++ program that exhibits counting semaphores (i.e. resource
counter) (15-marks):
You are required to write a scenario where counting semaphores are needed. Explain
the problem well and then write the code to solve the problem using counting
semaphores.
5
Solution:
Scenario where multiple threads need to access a shared printer:
Scenario: Imagine a scenario where there is a shared printer that multiple threads need to use to print
their respective documents. However, the printer can only handle a limited number of documents
simultaneously. To ensure fair and controlled access to the printer, counting semaphores are used.
Problem Explanation: The printer has a maximum capacity of 'N' documents that can be printed
concurrently. If all 'N' slots are occupied by other threads, a requesting thread needs to wait until a
slot becomes available. Once a slot becomes available, the requesting thread can access the printer
to print its document. When a thread finishes printing its document, it releases the slot, allowing other
threads to use it.
Solution/Coding using Counting Semaphores:
#include <iostream>
#include <thread>
#include <semaphore.h>
#include <unistd.h>
const int PRINTER_CAPACITY = 3;
//const int PRINTING_TIME = 2; // Time to simulate printing in seconds
sem_t countingSemaphore; // Semaphore for printer access
void printDocument(int threadId, int documentId) {
printf("Thread %d is requesting access to the printer for Document %d\n", threadId, documentId);
sem_wait(&countingSemaphore); // Acquire a slot in the printer
printf("Printer is printing Document %d for Thread %d\n", documentId, threadId);
// Simulating the printing process
//sleep(PRINTING_TIME);
printf("Printer finished printing Document %d for Thread %d\n\n", documentId, threadId);
sem_post(&countingSemaphore); // Release the slot in the printer
}
int main() {
sem_init(&countingSemaphore, 0, PRINTER_CAPACITY); // Initialize the semaphore
6
std::thread threads[5];
for (int i = 0; i < 5; i++) {
// Create threads for printing documents
threads[i] = std::thread(printDocument, i, i + 1);
}
for (int i = 0; i < 5; i++) {
// Wait for all threads to finish
threads[i].join();
}
sem_destroy(&countingSemaphore); // Destroy the semaphore
return 0;
}
Further Explanation:
The given code demonstrates the usage of counting semaphores in a scenario where multiple threads
need to access a shared printer. The printer has a limited capacity defined by the constant
PRINTER_CAPACITY, which is set to 3. The counting semaphore countingSemaphore is initialized to
manage access to the printer using sem_init.
The printDocument function represents the task of printing a document for a particular thread. Inside
this function, each thread requests access to the printer by calling sem_wait on the counting
semaphore. If the semaphore value is positive or zero (indicating available slots in the printer), the
thread proceeds and acquires a slot by decrementing the semaphore value. If the value is negative,
the thread is blocked and waits until a slot becomes available.
Once a slot is acquired, the thread proceeds to print the document and simulates the printing process
using sleep. After completing the printing, the thread releases the slot by calling sem_post to
increment the semaphore value, allowing other threads to access the printer.
In the main function, the counting semaphore is initialized with the printer capacity. Then, a set of
threads is created to represent the employees. Each thread calls the printDocument function with a
unique thread ID and document ID. Finally, the main function waits for all the threads to finish by
calling join, and the counting semaphore is destroyed using sem_destroy.
7
OUTPUT:
Download