以前写的读者写着问题:
unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
const
READERS=10; //Max readers at the same time
type
TfrmMain = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
btnDemo: TButton;
lbResult: TListBox;
btnClear: TButton;
btnClose: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnDemoClick(Sender: TObject);
procedure btnClearClick(Sender: TObject);
procedure btnCloseClick(Sender: TObject);
private
procedure Reader;
procedure Writer;
public
end;
var
frmMain: TfrmMain;
SemaR: THandle; //Semaphore of reader
SemaW: THandle; //Semaphore of writer
CountR: Integer; //Count of readers
Target: Integer; //The variable to be operated on
implementation
{$R *.dfm}
{ ++++++++Reader++++++++ }
procedure TfrmMain.Reader;
var
str: String;
H, M, S, Ms: Word;
begin
Randomize;
//Start time
DecodeTime(Time,H,M,S,Ms);
str:= Format('[ %-2d:%-2d:%-2d:%-3d => R ] The value is: ',[H,M,S,Ms]);
Sleep(Random(500));
If WaitForSingleObject(SemaR, INFINITE)=WAIT_OBJECT_0 Then
Try
If (CountR=0) Then WaitForSingleObject(SemaW, INFINITE);
CountR:= CountR+1;
Finally
ReleaseSemaphore(SemaR, 1, Nil);
End;
//Begin of reading
str:= str+IntToStr(target);
SendMessage(frmMain.lbResult.Handle,lb_addstring,0,longint(str));
Sleep(Random(500));
//End of reading
If WaitForSingleObject(SemaR, INFINITE)=WAIT_OBJECT_0 Then
Try
CountR:= CountR-1;
If (CountR=0) Then ReleaseSemaphore(SemaW, 1, Nil);
Finally
ReleaseSemaphore(SemaR, 1, Nil);
End;
end;
{ --------Reader-------- }
{ ++++++++Writer++++++++ }
procedure TfrmMain.Writer;
var
str: String;
H, M, S, Ms: Word;
begin
Randomize;
//Start time
DecodeTime(Time,H,M,S,Ms);
str:= Format('[ %-2d:%-2d:%-2d:%-3d => W ] The value is: ',[H,M,S,Ms]);
Sleep(Random(500));
If WaitForSingleObject(SemaW, INFINITE)=WAIT_OBJECT_0 Then
Try
//Begin of writing
target:= target+1;
str:= str+IntToStr(target);
SendMessage(frmMain.lbResult.Handle,lb_addstring,0,longint(str));
Sleep(Random(500));
//End of writing
Finally
ReleaseSemaphore(SemaW, 1, Nil);
End;
end;
{ --------Writer-------- }
procedure TfrmMain.FormCreate(Sender: TObject);
begin
SemaR:= CreateSemaphore(Nil, READERS, READERS, 'Reader');
SemaW:= CreateSemaphore(Nil, 1, 1, 'Writer');
CountR:= 0;
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
If SemaR<>0 Then CloseHandle(SemaR);
If SemaW<>0 Then CloseHandle(SemaW);
end;
procedure TfrmMain.btnDemoClick(Sender: TObject);
var
Id: DWord;
begin
CreateThread(Nil, 0, @TfrmMain.Reader, Nil, 0, Id);
CreateThread(Nil, 0, @TfrmMain.Writer, Nil, 0, Id);
CreateThread(Nil, 0, @TfrmMain.Reader, Nil, 0, Id);
CreateThread(Nil, 0, @TfrmMain.Writer, Nil, 0, Id);
CreateThread(Nil, 0, @TfrmMain.Reader, Nil, 0, Id);
CreateThread(Nil, 0, @TfrmMain.Writer, Nil, 0, Id);
CreateThread(Nil, 0, @TfrmMain.Reader, Nil, 0, Id);
CreateThread(Nil, 0, @TfrmMain.Writer, Nil, 0, Id);
CreateThread(Nil, 0, @TfrmMain.Reader, Nil, 0, Id);
CreateThread(Nil, 0, @TfrmMain.Writer, Nil, 0, Id);
end;
procedure TfrmMain.btnClearClick(Sender: TObject);
begin
lbResult.Clear;
end;
procedure TfrmMain.btnCloseClick(Sender: TObject);
begin
Close;
end;
end.