The Dining Philosophers Problem.Part 2. TPhilosopher class.© Lyapin Ilya
Dec 4, 2001
This article starts the detailed program explanation. Now let's look at the
philosopher.pas module that defines TPhilosopher class. TPhilosopher class definition.TPilosopher represents a philosopher's lifecycle. The main program creates five
instances of the TPhilosopher and run them concurrently. TPhilosopher is derived from the
TThread class (see previous articles for TThread details) and overrides Execute method. TPhilosopher class is defined like following: const
NUMBER_OF_PHILOSOPHERS = 5; // number of philosophers
type
// type for a status of a philosopher
TPhilosopherStatus =
(stUnknown,stThinking,stEating,stWaitingForLeftFork,stWaitingForRightFork); // the philosopher's life cycle -
thinking, waiting for fork, eating
TPhilosopher = class (TThread)
private
// the status of the philosopher
FStatus: TPhilosopherStatus;
// the number of the philosopher
FNumber: Integer;
// pointer to the fork manager
FForks: TForks;
protected
// the thread procedure
procedure Execute;override;
public
// constructor - initializes FNumber and FForks fields
and creates the suspended thread
constructor Create(iNumber:integer;Forks:TForks);
// Status of the philosopher - read only property
property Status:TPhilosopherStatus read FStatus;
// number of the philosopher - read only property
property Number: integer read FNumber;
end; Philosopher.pas globals.Each philosopher eats and thinks the same time. In order to change eating and thinking
time each pass we should use two global variables of type DWORD. var
EatingTime,
ThinkingTime:DWORD; Procedure SetTimes changes eating and thinking time. procedure SetTimes(dwEatingTime,dwThinkingTime:DWORD);
begin
EatingTime := dwEatingTime;
ThinkingTime:= dwThinkingTime;
end; TPhilosopher class implementation.Constructor TPhilosopher.Create initializes FNumber and FForks fields and creates the
suspended thread using inherited constructor. constructor TPhilosopher.Create(iNumber:
integer; Forks: TForks);
begin
// store the number of the philosopher
FNumber := iNumber;
// store the pointer to the fork manager
FForks := Forks;
// create suspended thread
inherited Create(true);
// the program will free philosopher object
manually
FreeOnTerminate := false;
end; The thread procedure implements the lifecycle of the philosopher.
While terminated property is not signaled, the philosopher fulfils the following actions:
- Think (sleep) a random time based on the ThinkingTime constant
- Call the fork manager to acquire left fork
- When the fork is granted call the fork manager to acquire right fork
- Eat (sleep) a random time based on the EatingTime constant
procedure TPhilosopher.Execute;
var
lf,rf:integer;
begin
// while thread is not terminated
while not terminated do
begin // philosopher is 'alive'
// Think a little
fStatus := stThinking;
Sleep(Random(ThinkingTime));
// Philosopher is hungry
// He sits at the table
fStatus :=stWaitingForLeftFork;
lf := FNumber - 2;
if lf<0 then
lf :=
NUMBER_OF_PHILOSOPHERS -1;
// ... And tries to take
the left fork
if
FForks.TakeFork(lf,INFINITE) then
begin
// fork granted - let's take the right fork
Go To Page:
1
2
The copyright of the article The Dining Philosophers Problem.Part 2. TPhilosopher class. in Delphi Programming is owned by . Permission to republish The Dining Philosophers Problem.Part 2. TPhilosopher class. in print or online must be granted by the author in writing.
|