P
Pc 狂迷
Unregistered / Unconfirmed
GUEST, unregistred user!
我想用 5 个线程产生 5 个不同的 [1..20] 的随机数,就写了这个 互斥同步 线程。
可得到的结果并不是我想要的 -- 有零。(为 BUG 更明显 我加了一句 sleep),前辈
们帮忙看看错在哪里?
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
ThreadRuning = class(TThread)
protected
procedure Execute;override;
end;
TfrmMain = class(TForm)
btnGO: TButton;
procedure btnGOClick(Sender: TObject);
private
procedure ThreadsDone(Sender: TObject);
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
const
ID = 5;
var
PNumber: array [1..ID] of integer;
Flags : integer = 0;
do
neFlags : integer = 0;
hMutex: THandle = 0;
PWNuberSet: Set of 1..20;
procedure ThreadRuning.Execute;
var
Number: integer;
LoopBool: boolean;
begin
LoopBool := True;
// Number := 0;
FreeOnTerminate := True;
OnTerminate := frmMain.ThreadsDone;
Inc(Flags);
while LoopBooldo
begin
if WaitForSingleObject(hMutex,INFINITE) = WAIT_OBJECT_0 then
begin
Number := Random(20) + 1;
if not(Number in PWNuberSet) then
begin
PNumber[Flags] := Number;
Include(PWNuberSet,Number);
LoopBool := false;
sleep(100);
end;
//if
end;
// if
end;
// while
end;
procedure TfrmMain.ThreadsDone(Sender: TObject);
var
i: integer;
begin
Inc(DoneFlags);
ifdo
neFlags = 5 then
begin
for i := 1 to 5do
ShowMessage(IntToStr(i) + ' : ' + IntToStr(PNumber));
CloseHandle(hMutex);
ShowMessage('End');
end;
// if
end;
procedure TfrmMain.btnGOClick(Sender: TObject);
begin
Flags := 0;
do
neFlags := 0;
PWNuberSet := PWNuberSet * [];
Randomize;
hMutex := CreateMutex(nil,false,nil);
ThreadRuning.Create(false);
ThreadRuning.Create(false);
ThreadRuning.Create(false);
ThreadRuning.Create(false);
ThreadRuning.Create(false);
end;
end.
可得到的结果并不是我想要的 -- 有零。(为 BUG 更明显 我加了一句 sleep),前辈
们帮忙看看错在哪里?
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
ThreadRuning = class(TThread)
protected
procedure Execute;override;
end;
TfrmMain = class(TForm)
btnGO: TButton;
procedure btnGOClick(Sender: TObject);
private
procedure ThreadsDone(Sender: TObject);
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
const
ID = 5;
var
PNumber: array [1..ID] of integer;
Flags : integer = 0;
do
neFlags : integer = 0;
hMutex: THandle = 0;
PWNuberSet: Set of 1..20;
procedure ThreadRuning.Execute;
var
Number: integer;
LoopBool: boolean;
begin
LoopBool := True;
// Number := 0;
FreeOnTerminate := True;
OnTerminate := frmMain.ThreadsDone;
Inc(Flags);
while LoopBooldo
begin
if WaitForSingleObject(hMutex,INFINITE) = WAIT_OBJECT_0 then
begin
Number := Random(20) + 1;
if not(Number in PWNuberSet) then
begin
PNumber[Flags] := Number;
Include(PWNuberSet,Number);
LoopBool := false;
sleep(100);
end;
//if
end;
// if
end;
// while
end;
procedure TfrmMain.ThreadsDone(Sender: TObject);
var
i: integer;
begin
Inc(DoneFlags);
ifdo
neFlags = 5 then
begin
for i := 1 to 5do
ShowMessage(IntToStr(i) + ' : ' + IntToStr(PNumber));
CloseHandle(hMutex);
ShowMessage('End');
end;
// if
end;
procedure TfrmMain.btnGOClick(Sender: TObject);
begin
Flags := 0;
do
neFlags := 0;
PWNuberSet := PWNuberSet * [];
Randomize;
hMutex := CreateMutex(nil,false,nil);
ThreadRuning.Create(false);
ThreadRuning.Create(false);
ThreadRuning.Create(false);
ThreadRuning.Create(false);
ThreadRuning.Create(false);
end;
end.