Lab 15: Synchronization #
Starting code #
There is a flash sale on the new “Lidlomix 3000”. Crowds are gathering outside the shop since dawn. To keep everything civil, the management has decided to enforce strict safety measures.
The program accepts three arguments:
M- number of customers (20 <= M <= 100)N- number of restock workers (3 <= N <= 12,N % 3 = 0)K- number of cashiers (2 <= K <= 5)
Your task is to simulate the shop operation using Tasks and asynchronous synchronization.
Stages: #
[3p] Create
Mcustomer tasks. The shop capacity is limited to8customers. Use aSemaphoreSlimto control access. Upon entering, the customer prints:CUSTOMER <ID>: Entered the shop, waits 200ms usingTask.Delay, and then leaves the shop (releasing the semaphore).[4p] Create
Nworker tasks for restocking. Carrying a device requires a team of 3 workers. Workers work in fixed teams of 3 in a loop until at leastMdeliveries are made across all teams. Use a barrier to synchronize teams. When 3 workers gather, they printTEAM <TEAM_ID>: Delivering stock, wait 400ms, and increment the stock count. Customers wait for stock if it’s 0. Once available, they decrement the count and printCUSTOMER <ID>: Picked up Lidlomix. You can use a semaphore for counting the stock.[3p] Implement a checkout queue. Instead of leaving immediately, customers must join a FIFO blocking collection with capacity of 5. If it’s full, the customer waits. Create
Kcashier tasks. A cashier takes a customer from the queue, printsCASHIER <CashID>: Serving Customer <CustID>, and waits 300ms. The customer must wait until the cashier finishes (you may use aSemaphoreSlim). Once done, the customer printsCUSTOMER <CustID>: Paid and leaving.[2p] Handle
SIGINT. All tasks must be notified to exit viaCancellationToken. Ensure no task is left hanging on any synchronization primitive (barrier, semaphore, or collection). Cleanup all resources.
Example solution #