10c1. Assignment 3
10c1. Assignment 3
# Section: Name
Problem Description:
In multithreaded programs there is often a division of labor between threads. In one common pattern, some
threads are producers and some are consumers. Producers create items of some kind and add them to a data
structure; consumers remove the items and process them. Event-driven programs are a good example. An
“event” is something that happens that requires the program to respond: the user presses a key or moves the
mouse, a block of data arrives from the disk, a packet arrives from the network, a pending operation completes.
Whenever an event occurs, a producer thread creates an event object and adds it to the event buffer.
Concurrently, consumer threads take events out of the buffer and process them. In this case, the consumers are
called “event handlers.”
There are synchronization constraints that are required to enforce to make this system work correctly:
• While an item is being added to or removed from the buffer, the buffer is in an inconsistent state. Therefore,
threads must have exclusive access to the buffer.
• If a consumer thread arrives while the buffer is empty, it blocks until a producer adds a new item.
Objective:
Analyze the above problem and write the pseudocode that enforces synchronization constraints for the
above problem considering the following synchronization constraints should apply:
• If each thread has its own run-time stack, then any variables allocated on the stack are thread-specific.
• If threads are represented as objects, we can add an attribute to each thread object.
• If threads have unique IDs, we can use the IDs as an index into an array or hash table, and store per-
thread data there.
1
Report submission:
The report must contain the following information,
1. Introduction
2. Literature review and background
3. Block diagram
4. Pseudocode
5. Dry run for possible scenarios
6. Conclusion and limitations
7. References (Books, websites and research papers)
2
1. Introduction :
The barbershop problem is a classic example of a concurrency problem that involves multiple
threads accessing shared resources. In this problem, there are three barbers, three barber chairs,
and a waiting area that can accommodate four customers on a sofa and that has standing room
for additional customers. The fire codes limit the total number of customers in the shop to 20.
Semaphores are a synchronization tool that can be used to control access to shared resources. By
using semaphores, we can ensure that the shared resources are used correctly and efficiently, and
that the synchronization constraints are met.
3. Block Diagram:
4. Pseudo Code:
5. Queue customerQueue //
Initialize queue for customers
6. Queue barberQueue //
Initialize queue for barbers
7. class Customer {
8. enterShop() {
9. if (shopCapacity.value ==
0) { // Check if shop is at
capacity
11. }
12. shopCapacity.decrement(
) // Decrement the shop
capacity semaphore
13. customerQueue.enqueue(this)
// Add customer to queue
14. }
15. sitOnSofa() {
26. barberQueue.enqueue(this) // Add
19. sofaCapacity.decrement() // customer to barber queue
Decrement the sofa capacity
semaphore 27. customerQueue.dequeue() // Remove
customer from customer queue
20. }
28. }
21. sitInBarberChair() {
29. pay() {
22. if (barberChairCapacity.value == 0) { //
Check if all barber chairs are busy 30. wait(cashRegister) // Wait for the
cash register to be available
23. wait(barberChairCapacity) // Wait for a
customer to finish their haircut 31. cashRegister.decrement() //
Decrement the cash register
24. } semaphore
25. barberChairCapacity.decrement() //
32. }
Decrement the barber chair capacity
semaphore 33. exitShop() {
35. } 5. Methodology:
36. }
38. cutHair() {
39. Customer c =
barberQueue.dequeue() // Get
the next customer in line for a
haircut
47. cashRegister.increment() //
42. // cutting hair
Increment the cash register
43. signal(c.pay) // Signal the customer semaphore
that it's their turn to pay
48. signal(barberQueue.peek().exitShop) //
44. } Signal the next customer in line that they
45. acceptPayment() { can now exit the shop
2. Queue customerQueue and barberQueue are used to keep track of the order of arrival
of customers and the order in which customers are served by the barbers.
3. The class Customer represents a customer and defines the functions enterShop,
sitOnSofa, sitInBarberChair, pay, and exitShop that a customer will invoke in the
given order.
4. The class Barber represents a barber and defines the functions cutHair and
acceptPayment that a barber will invoke.
5. The enterShop function checks if the shop is at capacity, if it is at capacity then waits for
the shopCapacity semaphore to be incremented. If the shop is not at capacity, the
customer decrements the shopCapacity semaphore and adds himself to the
customerQueue.
6. The sitOnSofa function checks if the sofa is full, if it is full then waits for the
sofaCapacity semaphore to be incremented. If the sofa is not full, the customer
decrements the sofaCapacity semaphore.
7. The sitInBarberChair function checks if all barber chairs are busy, if they are busy then
waits for the barberChairCapacity semaphore to be incremented. If a barber chair is
available, the customer decrements the barberChairCapacity semaphore and adds
himself to the barberQueue, also removes himself from the customerQueue.
10. The cutHair function takes the next customer in the barberQueue and signals the
sofaCapacity and barberChairCapacity semaphores, also signals the pay function of
the customer.
11. The acceptPayment function waits for the cashRegister semaphore to be incremented.
Then it increments the cashRegister semaphore and signals the exitShop function of the
customer who just finished paying.
3. if (shopCapacity.value ==
0) { // check if the shop is
at capacity
4. wait(shopCapacity) // wait
for a customer to exit the
shop
5. }
6. shopCapacity.decrement(
) // decrement the shop
capacity semaphore
8. sitOnSofa() // call the sitOnSofa 12. wait(sofaCapacity) // wait for a
function customer to leave the sofa
9. } 13. }
17. if (barberChairCapacity.value
== 0) { // check if all barber
chairs are busy
18. wait(barberChairCapacity) //
wait for a customer to finish
their haircut
19. }
20. barberChairCapacity.decrement(
) // decrement the barber chair
capacity semaphore
21. barberQueue.enqueue(this) //
add customer to barber queue
22. customerQueue.dequeue() //
remove customer from
customer queue
24. }
27. cashRegister.decrement(
) // decrement the cash
register semaphore
41. }
32. }
42. void acceptPayment() {
33. }
43. wait(cashRegister) // wait for the
34. class Barber {
cash register to be available
35. void cutHair() {
44. cashRegister.increment() //
36. Customer c = increment the cash register
barberQueue.dequeue() // get the next semaphore
customer in line for a haircut
45. signal(barberQueue.peek().exitShop) //
37. signal(sofaCapacity) // signal that a signal the next customer in line that they
sofa spot is now available can now exit the shop
8. Limitations:
1. It doesn't take into account the time it takes for a customer or barber to complete a
specific task.
2. It doesn't handle the case where a barber takes more time to cut a customer's hair than
another customer has been waiting, this could cause starvation.
3. It doesn't handle the case where a customer leaves the shop without paying, this could
cause issues with the cashier.
4. It doesn't consider the case where a customer leaves the shop without getting a hair cut,
References:
2. Tanenbaum, A.S., & Bos, H. (2019). Modern Operating Systems (5th ed.). Pearson.
3. Silberschatz, A., Galvin, P.B., & Gagne, G. (2018). Operating System Concepts (10th
ed.). John Wiley & Sons.
5. https://core.ac.uk/download/pdf/82196744.pdf
6. https://dl.acm.org/doi/pdf/10.1145/948101.948103
7. https://doi.org/10.1016/0167-6377(87)90023-X
8. https://ro.uow.edu.au/cgi/viewcontent.cgi?referer=&httpsredir=1&article=1027&conte
xt=compsciwp
9. https://pure.rug.nl/ws/portalfiles/portal/2400325/2013FormAspCompHesselink.pdf
---------------------------------------------------------------------------------------------------------------------