I. Project Purpose
The purpose of this project was to create a hotel simulation using threads and semaphores, allowing for concurrency. In this project we explored concepts relating to threads, parallel processing, semaphores, shared resources, and concurrency. This project helped solidify concepts relating shared memory, race conditions, deadlocks, mutual exclusion, and multiprocessing components. The overall objective of this project was to create a process that simulates the experience of a guest from check in to retiring. There were 25 guests, 2 bellhops, and 2 front desk employees, each of these components was controlled by a thread and the synchronization between the threads were made through semaphores. Some of the deliverables included: a function for the guest, bellhop and front desk, an main function that created and joined the treads.
II. Project Implementation
a. Implementation of the Guest Threads (25)
The guest thread begins by assigning the thread ID to a local variable called GuestID and then printing that “the guest (thread_num) has entered the hotel with X number of bags”. Next the guest ID/ thread ID is enqueued in the frontdeaskline queue. This operation is protected by a mutex so that only one thread can add to the global frontdeaskline queue at a time. Following that the guest is signaled to be ready which allows synchronization between the guest and front desk thread. Next the guest threads wait for the front desks operations to complete for the guest associated with the thread. This is done using an array of semaphores that signal when a particular guest is completed. After the signal is received, the guest post that it has received the key and frees up the front desk resource. Following this execution depends on the number of bags the guest has. If the guest has less than or equal to 2 bags, then the guest simply enters the room and retires for the evening. Otherwise, the guest waits for a bellhop resource to be availed and prints that they “need help with bags”. Next, the guest is queued in the bellhop line. Here we use another mutex to protect the insertion into the bellhop queue. Then we post that the guest is available for the bellhop to activate the bellhop resource. Following that the guest waits for the bellhop to signal that they have received the bags. Upon receipt, the guest heads to their room and post that they have reached their room. In the bellhop threads once that guest is processed, the bell hop signals the delivery of the bags. Next the guest waits for the bags to be delivered and tips the bellhop on delivery and release the resource. Lastly, the guest retires for the evening.
b. Implementation of Bellhop Threads (2)
The bellhop thread is only activated when there is a guest ready and there are bellhops’ resources available. First the bellhop thread dequeues from the bellhop queue. This operation is protected with a mutex so that two threads are not able to dequeue at the same time. Next the bellhop prints out and signals that it has received the bags of the guest that was pulled from the queue. Next the bellhop waits for the guest to reach their room. After the guest has reached their room, the bell hop prints and signals the delivery statement and waits for the guest thread the release the bellhop.
c. Implementation of Front desk Threads (2)
The front desk thread is activated when there are front desk employees available, and the guest is ready (enqueued). The thread operations are relativity simple; the guest id is popped of from the queue in a protected environment. The threads assign a room to that guest and signals that the front desk side of transaction is done for a particular guest and waits for the guest to acknowledge and release the front desk resource.
d. Implementation of main function
The main function was used to initialize all the semaphores, create the threads, and join the guest threads. In terms of initializing the semaphore, most semaphores were set to 0 and activated through the signal calls in the functions. The mutex, bellhop and front desk ready semaphore set to 1, 2, 2 respectively. The mutex semaphore were set to 1 since the global variables protected required initial access before through the wait statement before implementing the signal at the end of the critical section. The bellhop and front desk ready were set to 2 since there were two of each resource available at the beginning of the simulation. Additionally, the random number of bags for each guest was also assigned in the main function. This was done through storing the random results in an array of 25 and then access that array in the threads. The random number were generated through using the random library and the distribution function. Furthermore, all the threads were created using for loops and the number of the guest, bellhop or front employee was passed as an argument to the thread. Lastly, a “join” statement was issued for each of the guest threads and when all the guest threads joined successfully the program was ended. There were no join statements issued for bellhop and front desk threads since they use an infinite loop.