Philosophers dining problem
Solution: Set five philosophers were numbered A, B, C, D and E and placed the table . All five philosophers are very polite and have to get two chopsticks beside them at the same time.Before eating, or just waiting to continue thinking, but also immediately after eating a dish and then immediately put down two chopsticks in his hand, continue to think.
With the P V primitive way to achieve the problem. Each philosopher can use a single thread to simulate and the semaphore and its P, V operations Define a semaphore class encapsulation P V primitive analog functions.
May wish to have six philosophers, six chopsticks, chopsticks each corresponding to a semaphore and the initial value of each semaphore which should be 1.
//semaphore.h
#ifndef SEMAPHORE_H
#define SEMAPHORE_H
#include
class Semaphore {
protected:
HANDLE sem;
public
Semaphore (unsigned int SemValue);
virtual ~ Semaphore ();
void P ();
void V ();
#endif
//semaphore.cpp
#include
#include
#include
#include "semaphore.h"
Semaphore :: Semaphore (unsigned int semValue) {
if (semValue> LONG_MAX)
semValue = LONG_MAX;
sem = CreateSemaphore (NULL, semValue, LONG_MAX, NULL);
Semaphore :: ~ Semaphore () {
CloseHandle (sem);
void Semaphore :: P () {
DWORD dw = WaitForSingleobject (sem, INFINITE);
assert (dw == WAIT_object_0);
void Semaphore :: V () {
ReleaseSemaphore (sem, 1, NULL);
//thread.h
#ifndef THREAD_H
#define THREAD_H
#include
#include
from MSDN:
Start address of a routine that begins execution of a new thread.
For _beginthread, the calling convention is either __cdecl or __clrcall;
for _beginthreadex, it is either __stdcall or __clrcall.
WINAPI is __stdcall
typedef unsigned int (WINAPI * PTHREAD_START) (void *);
chBEGINTHREADEX is From
#define chBEGINTHREADEX (psa, cbStackSize, pfnStartAddr, \
pvParam, dwCreateFlags, pdwThreadId) \
((HANDLE) _beginthreadex (\
(void *) (psa), \
(unsigned) (cbStackSize), \
(PTHREAD_START) (pfnStartAddr), \
(void *) (pvParam), \
(unsigned) (dwCreateFlags), \
(unsigned *) (pdwThreadId)))
#define startThread (pfnStartAddr, pvParam) \
chBEGINTHREADEX (NULL, 0, (pfnStartAddr), (pvParam), 0, NULL)
#endif
//main function
#include
#include "semaphore.h"
#include "thread.h"
#include
#include
#define N 6 // The number of philosophers
#define LEFT (i) (i + N-1)% N // The left chopstick
#define RIGHT (i) (i == N-1)? 0: (i + N)% N // The chopstick number to the right of the philosopher with the chopstick number N on the right is 0
// Initialization of semaphores
Semaphore ChopStick [N] = {Semaphore (1), Semaphore (1), Semaphore (1), Semaphore (1), Semaphore (1), Semaphore (1)};
//Philosopher's state
void Eating (int Ph_Id)
printf ("Philosopher% d: \ tI'm eating ...... \ t", (int) Ph_Id);
void Sleeping (int Ph_Id)
printf ("Philosopher% d: \ tI'm sleeping ... \ t", (int) Ph_Id);
Sleep (rand ()% 10000);
void Thinking (int Ph_Id)
printf ("Philosopher% d: \ tI'm thinking ... \ t", (int) Ph_Id);
if (pid% 2 == 0) // even number philosopher
Thinking (pid); // Waiting
ChopStick [LEFT (pid)]. P (); // pick up the chopsticks on the left and pick up the chopsticks on the right
ChopStick [RIGHT (pid)]. P ();
Eating (pid); // The two semaphores are eating
ChopStick [LEFT (pid)]. V (); / / release the left and right semaphores
ChopStick [RIGHT (pid)]. V ();
printf ("\ n");
else if (pid% 2 == 1) // Odd philosopher
Thinking (pid);
ChopStick [RIGHT (pid)]. P (); // pick up the chopsticks on the right and pick up the chopsticks on the left
ChopStick [LEFT (pid)]. P ();
Eating (pid); // Eating around after getting chopsticks
ChopStick [RIGHT (pid)]. V (); // Releases the right and left semaphores successively
ChopStick [LEFT (pid)]. V ();
printf ("\ n");
Sleeping (pid); // eat and sleep for a while
int main () {
HANDLE hPhilosopher [N]; // Assign each philosopher a thread
int count = 0;
for (int Philosopher_id = 0; Philosopher_id
hPhilosopher [Philosopher_id] = startThread (Philosopher, Philosopher_id);
if (count> 5)
break;
:: WaitForMultipleobjects (N, hPhilosopher, TRUE, INFINITE);
for (Philosopher_id = 0; Philosopher_id
CloseHandle (hPhilosopher [Philosopher_id]);