L3: Bitronka#
The year is 2025. In Bitronka—the modern retail empire—chaos still reigns. In the heat of the daily battle over whole-grain rolls, store customers create disarray on the store shelves. They swap the positions of chips with yogurts, squeeze apples between pears. Chewing gum? Best placed next to the butter. A can of pineapples? What if it ends up in the dairy section? The worst of all is Mrs. Hermina, who transfers AA batteries to the frozen food section every day because “it’s cooler here.” Not to mention the pallets blocking the aisles, the store is in utter disarray.
In the evenings, when the last customer leaves with a bag full of candies weighed as onions, employees step in to tackle the cleaning process, attempting to restore order. “These batteries in frozen food AGAIN!?” someone shouts, and the echo carries as far as the fruit section. Employees know that organizing the store is a losing battle, as chaos will return with the first door opening the next morning. But they persevere. Each of them randomly selects a pair of products from the shelves and decides if their positions need adjustment. If so, the products are moved to the correct (or at least more logical) positions.
Your task is to write a simulation of store operations, where chaos persists during the day, and employees attempt to organize the store shelves each night, even if only temporarily. The simulation should use multithreading and signal handling.
Global and static variables are NOT allowed.
Stages#
Stage 1 (3 points)#
The program accepts two parameters: \( 8 \le N \le 256 \) - the number of products, and \( 1 \le M \le 16 \) - the number of employees. Introduce \( M \) employee threads. Each employee prints Worker <index>: Reporting for the night shift! and finishes. The main thread waits for all threads to complete.
Stage 2 (5 points)#
The store is represented as a one-dimensional array of size \( N \), where each index of the array corresponds to a shelf, and its value is the current product (an integer from \( 1 \) to \( N \)). Each product is protected by a dedicated mutex. At the start of the program, shuffle the array using the shuffle method. After reporting in, each employee randomly selects two different indices from the range ([1, N]) 10 times and sleeps for 100 ms. If the products at these indices are in the wrong order (i.e., the value at the first index is greater than the second), they swap them to increase the orderliness of the shelves, while sleeping 50 ms.
Stage 3 (5 points)#
Employees now work until receiving the SIGINT signal. Introduce a dedicated thread for signal handling—for SIGINT, this thread sets a shared flag notifying employees that the work has ended. The main thread waits for all threads to complete.
Stage 4 (5 points)#
Add handling for the SIGALRM and SIGUSR1 signals. Upon receiving SIGALRM, the thread prints the current state of the store shelves and sets the next alarm for the following second. The thread waiting for signals sets the first alarm for one second. Upon receiving SIGUSR1, the thread reshuffles the shared array. Remember to lock access to the entire array for both operations.
Stage 5 (6 points)#
Add handling for the SIGUSR2 signal. Upon receiving the SIGUSR2 signal, one random employee thread is canceled. Once all employee threads are canceled, the program terminates.