hobbielektronika
/
10_rtos_dpp_mutex
Dining Philosophers Problem solved by the help of mutexes
main.cpp
- Committer:
- icserny
- Date:
- 2016-02-10
- Revision:
- 0:1424c0020312
File content as of revision 0:1424c0020312:
/** 10_rtos_dpp_mutex * The dining philosophers problem is invented by E. W. Dijkstra. * Imagine that five philosophers sitting around a round table with five chairs, * who spend their lives alternating between thinking and eating * from a large bowl of rice at random intervals. * However, there are only five chopsticks available at the right hand and * left hand of each philosopher. Each philosopher thinks. When he gets hungry, * he picks up the two chopsticks that are closest to him. If a philosopher can pick * up both chopsticks, he eats for a while. After a philosopher finishes eating, * he puts down the chopsticks and starts to think again. * * Since the chopsticks are shared between the philosophers, access to the chopsticks * must be protected, but if care isn't taken, concurrency problems arise. Most notably, * starvation via deadlock can occur: if each philosopher picks up a chopstick as soon * as it is available and waits indefinitely for the other, eventually they will all end * up holding only one chopstick with no chance of acquiring another. * * In this solution we instruct our philosophers to cooperate: to put down the * acquired chopstick, if the second is not available, and wait for a (short) random interval. * This is the same techniqe used by the network cards when they detected packet collision. * * The five chopsticks are represented by five mutexes. * The philosophers are represented as threads. * * Hardware requirements: * - FRDM-KL25Z board */ #include "mbed.h" #include "rtos.h" Mutex stdio_mutex; Mutex chopstick[5]; //Array of mutexes representing the 5 chopsticks void notify(int num, int state) { stdio_mutex.lock(); if(state) { printf("Philospher %d is EATING \n\r", num); } else { printf("Philospher %d is thinking \n\r", num); } stdio_mutex.unlock(); } void philosopher(void const *args) { while (true) { if(chopstick[(int)args-1].trylock()) { if(chopstick[(int)args%5].trylock()) { notify((int)args,1); //Start EATING Thread::wait(1000+rand()%1000); chopstick[(int)args%5].unlock(); //Release chopsticks chopstick[(int)args-1].unlock(); notify((int)args,0); //Start Thinking Thread::wait(2000+rand()%2000); //Get's hungry after this time... } else { chopstick[(int)args-1].unlock(); Thread::wait(100+rand()%100); //Wait for random time if failed } } else { Thread::wait(100+rand()%100); //Wait for random time if failed } } } int main() { Thread t2(philosopher, (void *)2U); Thread t3(philosopher, (void *)3U); Thread t4(philosopher, (void *)4U); Thread t5(philosopher, (void *)5U); philosopher((void *)1U); }