constructor Table.Create;
begin
Handle := CreateSemaphore(nil, 0, 1, nil);
FreeOnTerminate := True;
List:=TList.Create;
while List.Count<100do
AddPhilosopher;
Half:=List.Count shr 1;
inherited Create(False);
end;
destructor Table.Destroy;
var
n:integer;
begin
CloseHandle(Handle);
inherited Destroy;
end;
procedure Table.AddPhilosopher;
var
P
Act;
begin
New(P);
with P^do
begin
Pr:=Philosopher.Create;
Active:=True;
Dinner:=0;
PHandle:=P^.Pr.Handle;
end;
List.Add(P);
end;
procedure Table.Execute;
begin
while Truedo
begin
if List.Count< 1 then
exit;
if WaitForSingleObject(Handle,Random(100))<>WAIT_TIMEOUT then
begin
if (DinnerCount<=Half)and(Index>=0) then
begin
PAct(List[Index])^.Active:=True;
Inc(PAct(List[Index])^.Dinner);
if PAct(List[Index]).Dinner>365 then
// 蹭够了?
begin
TerminateThread(PAct(List[Index]).PHandle,0);
List.Delete(Index);
end else
Next.Resume;
end;
end
else
begin
Next:=NextPhilosopher;
ReleaseSemaphore(Handle,1, nil);
end;
end;
end;
function Table.NextPhilosopher
hilosopher;
var
do
ne: Boolean;
m, n: integer;
Ptr: Pointer;
FList:TList;
begin
FList:=TList.Create;
try
for m:=0 to List.Count-1do
begin
if (PAct(List[m]))^.Active then
if (PAct(List[m]))^.Pr.Thinking then
(PAct(List[m]))^.Active:=False;
if not((PAct(List[m]))^.Active)then
FList.Add(List[m]);
end;
n := FList.Count;
repeat
do
ne := True;
for m := 0 to n - 2do
if (PAct(FList[m]))^.Dinner >(PAct(FList[m+1]))^.Dinner then
begin
ptr := FList[m];
FList[m] := FList[m + 1];
FList[m + 1] := ptr;
do
ne := False;
end;
untildo
ne;
if FList.Count>0 then
begin
Index:=List.IndexOf(FList[0]);
Result:=PAct(List[Index])^.Pr;
end;
finally FList.Free;
end;
end;