Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

In C programming language: Part 1 (10 points): Creation of Simple Threads In this part, you will create a main program that takes a single

In C programming language:image text in transcribed

Part 1 (10 points): Creation of Simple Threads In this part, you will create a main program that takes a single command line parameter (an integer) to indicate the number of threads to be created. You can finish this part by following these steps: (1) process the command line parameter to retrive the value of nthreads (2) print your name followed by "Assignment 4: # of threads-" and the value of nhreads (3) then the main program invoke the function void creatPhilosophers(int nthreads) where nthreads is the parameter for the number of threads to be created. To create each thread, the function philosopher Thread(int i) wil be called with an integer parameter as the index of the thread (4) for each philosopher thread, the function philosopherThread) can simply output a statement like "This is philosopher X", where X is the index of the thread. After that, the thread function can just return NULL (5) In the function creatPhilosophers), the main thread needs to wait for the completion of all philosopher threads using the function pthread join). Once all created threads join successfully, the function creatPhilosophers0 can print out a message saying "N threads have been completed joined successfully!" and return; Please name the source code for this part as "assign4-part.c". Please test with 5 and 20 for nthread. The output should be included in the Report.txt under the Section: Part I. Moreover, please briefly explain how you have utilized the function pthread_join) in the report. Part 2 (30 points): Use multiple Mutexes for Chopsticks In this part, you are going to simulate the activities of the philosophers, where each philosopher is in a"thinking"-"picking up chopsticks"- "eating"- "putting down chopsticks" cycle as shown below. That is, you need to creat four different functions to implement these four steps correspondingly, where these functions have the deterministic signatures as follows: void thinking) void pickUpChopsticks(int threadIndex) void eatingo void putDownChopsticks(int threadndex) The function pickUpChopsticks0 that simulates the activity of "pick up chopsticks" is the key function of this assignment. Note that, each chopstick is shared by two neighbor philosophers and hence is a shared resource. We certainly can not let a philosopher to pick up a chopstick that has already been picked up by the neighbor philosopher, which will be a race condition. To address this problem, we can implement each chopstick as a mutex lock. Each philosopher, before cating, needs to lock the left chopstick and the right chopstick. Only after the acquisitions of both locks (hence two chopsticks) are successful, can this philosopher start to eat. After finishes eating by calling the function eating), the philosopher will invoke the function putDownChopsticks0 to release both locks (i.e., chopsticks), and exit the program (that is, for Part 2, each philosopher only goes through the above cycle once!). Both functions eating0 and thinking0 can be easily simulated by invoking a sleep function, such as usleep), between two output statements Philosopher # : start eating thinking and Philosopher : end eating thiking respectivelv However, we should not use a fixed value for every invocation of the sleep function to emulate the different length of activites of the philosophers. Instead, we need to utilize a random number between 1 to 500. You can use function random to get a random value, which could be inied using function srandom) with a proper seed value for the random value generator. Please google or use the man pages of these functions to find out how to use them. In general, two problems may arise in carelessly designed synchronization solution: starvation and deadlock (see the link for more descriptions of these two problems). For the above simple solution, where each philosopher only eats once and exit, there will be no starvation issue. However, the solution may still lead to deadlocks. In particular, when every philosopher sits down and picks up his left chopstick at the same time, a deadlock will occur. In this case, all chopsticks are locked and none of the philosophers can successfully lock the right chopstick, which leads to a circular waiting situation (i.e., every philosopher waits for the right chopstick that is currently being locked by the right neighbor). Notel: Name your program for this part as "assign4-part2.c" Again, you need to test the program with 5 threads and 20 threads, and add the output in the Report.txt in Section: Part 2 Note2: Moreover, please run the program 100 times, and report the number of deadlocks encountered in the Report.txt Part 3 (30 points): Ordered Eating In this part, the deadlock problem in the solution for Part 2 will be addressed by using only one global mutex object for synchronization. In addition, the solution for this part needs to enforce the order of eating, where the philosopher with index 0 should eat first, followed by the one with index 1, and so on. The ordered eating can be achived with a conditional variable, which works together with nextlndex to indicate which philosopher should eat next. Initially, before creating all philosopher threads, nextIndex is set as 0 Here, when the i (th) philosopher thread completes thinking, the thread should check whether it is the i {th) philosopher's turn to eat or not before grabbing the chopsticks. If next naer==i, the i {th} philosopher will grab both chopsticks and start eating: Otherwise, if nextIndex!-i, the thread should wait on the shared conditional variable. When a philosopher thread completes eating, it wll increment the value of nextlndex and release the lock to wake up all threads that are waiting on the conditional variable. Depending on the value of nextlndex, only one of the thead can move forward based on the determined order, where other threads will have to go back to wait again. Note: Name your program for this part as "assign4-part3.c". Again, test the program with 5 and 20 threads. Run this program 10 times and confirm that there is no deadlock. Please include the output for one running of the case of 5 threads in the "Report.txt" under Section: Part 3. Moreover, please explain how you design your conditional variables to enforce the order of eating. You can copy the key part of your code to help your explanation. Part 1 (10 points): Creation of Simple Threads In this part, you will create a main program that takes a single command line parameter (an integer) to indicate the number of threads to be created. You can finish this part by following these steps: (1) process the command line parameter to retrive the value of nthreads (2) print your name followed by "Assignment 4: # of threads-" and the value of nhreads (3) then the main program invoke the function void creatPhilosophers(int nthreads) where nthreads is the parameter for the number of threads to be created. To create each thread, the function philosopher Thread(int i) wil be called with an integer parameter as the index of the thread (4) for each philosopher thread, the function philosopherThread) can simply output a statement like "This is philosopher X", where X is the index of the thread. After that, the thread function can just return NULL (5) In the function creatPhilosophers), the main thread needs to wait for the completion of all philosopher threads using the function pthread join). Once all created threads join successfully, the function creatPhilosophers0 can print out a message saying "N threads have been completed joined successfully!" and return; Please name the source code for this part as "assign4-part.c". Please test with 5 and 20 for nthread. The output should be included in the Report.txt under the Section: Part I. Moreover, please briefly explain how you have utilized the function pthread_join) in the report. Part 2 (30 points): Use multiple Mutexes for Chopsticks In this part, you are going to simulate the activities of the philosophers, where each philosopher is in a"thinking"-"picking up chopsticks"- "eating"- "putting down chopsticks" cycle as shown below. That is, you need to creat four different functions to implement these four steps correspondingly, where these functions have the deterministic signatures as follows: void thinking) void pickUpChopsticks(int threadIndex) void eatingo void putDownChopsticks(int threadndex) The function pickUpChopsticks0 that simulates the activity of "pick up chopsticks" is the key function of this assignment. Note that, each chopstick is shared by two neighbor philosophers and hence is a shared resource. We certainly can not let a philosopher to pick up a chopstick that has already been picked up by the neighbor philosopher, which will be a race condition. To address this problem, we can implement each chopstick as a mutex lock. Each philosopher, before cating, needs to lock the left chopstick and the right chopstick. Only after the acquisitions of both locks (hence two chopsticks) are successful, can this philosopher start to eat. After finishes eating by calling the function eating), the philosopher will invoke the function putDownChopsticks0 to release both locks (i.e., chopsticks), and exit the program (that is, for Part 2, each philosopher only goes through the above cycle once!). Both functions eating0 and thinking0 can be easily simulated by invoking a sleep function, such as usleep), between two output statements Philosopher # : start eating thinking and Philosopher : end eating thiking respectivelv However, we should not use a fixed value for every invocation of the sleep function to emulate the different length of activites of the philosophers. Instead, we need to utilize a random number between 1 to 500. You can use function random to get a random value, which could be inied using function srandom) with a proper seed value for the random value generator. Please google or use the man pages of these functions to find out how to use them. In general, two problems may arise in carelessly designed synchronization solution: starvation and deadlock (see the link for more descriptions of these two problems). For the above simple solution, where each philosopher only eats once and exit, there will be no starvation issue. However, the solution may still lead to deadlocks. In particular, when every philosopher sits down and picks up his left chopstick at the same time, a deadlock will occur. In this case, all chopsticks are locked and none of the philosophers can successfully lock the right chopstick, which leads to a circular waiting situation (i.e., every philosopher waits for the right chopstick that is currently being locked by the right neighbor). Notel: Name your program for this part as "assign4-part2.c" Again, you need to test the program with 5 threads and 20 threads, and add the output in the Report.txt in Section: Part 2 Note2: Moreover, please run the program 100 times, and report the number of deadlocks encountered in the Report.txt Part 3 (30 points): Ordered Eating In this part, the deadlock problem in the solution for Part 2 will be addressed by using only one global mutex object for synchronization. In addition, the solution for this part needs to enforce the order of eating, where the philosopher with index 0 should eat first, followed by the one with index 1, and so on. The ordered eating can be achived with a conditional variable, which works together with nextlndex to indicate which philosopher should eat next. Initially, before creating all philosopher threads, nextIndex is set as 0 Here, when the i (th) philosopher thread completes thinking, the thread should check whether it is the i {th) philosopher's turn to eat or not before grabbing the chopsticks. If next naer==i, the i {th} philosopher will grab both chopsticks and start eating: Otherwise, if nextIndex!-i, the thread should wait on the shared conditional variable. When a philosopher thread completes eating, it wll increment the value of nextlndex and release the lock to wake up all threads that are waiting on the conditional variable. Depending on the value of nextlndex, only one of the thead can move forward based on the determined order, where other threads will have to go back to wait again. Note: Name your program for this part as "assign4-part3.c". Again, test the program with 5 and 20 threads. Run this program 10 times and confirm that there is no deadlock. Please include the output for one running of the case of 5 threads in the "Report.txt" under Section: Part 3. Moreover, please explain how you design your conditional variables to enforce the order of eating. You can copy the key part of your code to help your explanation

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

New Trends In Databases And Information Systems Adbis 2019 Short Papers Workshops Bbigap Qauca Sembdm Simpda M2p Madeisd And Doctoral Consortium Bled Slovenia September 8 11 2019 Proceedings

Authors: Tatjana Welzer ,Johann Eder ,Vili Podgorelec ,Robert Wrembel ,Mirjana Ivanovic ,Johann Gamper ,Mikolaj Morzy ,Theodoros Tzouramanis ,Jerome Darmont

1st Edition

3030302776, 978-3030302771

More Books

Students also viewed these Databases questions