全部博文(788)
分类:
2009-04-08 09:22:44
帮你顶
拥有mutex的线程是不会被锁定的,可以一直重入,它只会锁定其他线程。
通过WaitForSingleObject递增mutex内部计数,ReleaseMutex递减mutex内部计数。
楼上正解~~~~
因为LZ的GetIdleMemo函数一直是由线程TDispThd来调用的,所以一直都可重入WaitForMultiOjbect,将GetIdleMemo这个函数放在TWorker.Execute执行,即可;
如下所示,我改了一下代码,是可以的.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
Memo3: TMemo;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TDispThd = class(TThread)
private
ConnMutexUse: array[0..2] of THandle;
protected
procedure Execute; override;
public
constructor Create(Mone: TMemo; Mtwo: TMemo; Mthree: TMemo);
end;
TWorker = class(TThread)
private
FMemo: TMemo;
FTID: integer;
FIndex: integer;
protected
procedure Execute; override;
procedure UpdateMemo;
public
constructor Create(index, id: integer; memo: TMemo);overload;
constructor Create(index: integer); overload;
end;
var
Form1: TForm1;
ConnMutexUse: array[0..2] of THandle;
MemoArr: array[0..2] of TMemo;
procedure GetIdleMemo(var id: integer);
implementation
{$R *.dfm}
procedure GetIdleMemo(var id: integer);
var
WaitRes: integer;
begin
WaitRes := WaitForMultipleObjects(3, @ConnMutexUse, FALSE, INFINITE);
id := WaitRes - WAIT_OBJECT_0;
if (id < 0) or (id > 2) then
raise Exception.Create('GetIdle错误');
end;
{ TWorker }
constructor TWorker.Create(index, id: integer; memo: TMemo);
begin
FMemo := memo;
FTID := id;
FIndex := index;
FreeOnTerminate := true;
inherited Create(false);
end;
constructor TWorker.Create(index: integer); //增加一个构造函数
begin
FIndex := index;
FreeOnTerminate := true;
inherited Create(false);
end;
procedure TWorker.Execute;
var
waitres: integer;
begin
GetIdleMemo(FTID);
FMemo := MemoArr[FTID];
try
Synchronize(UpdateMemo);
Sleep(3500); //时间调短,大于3*1000即可
finally
ReleaseMutex(ConnMutexUse[FTID]);
end;
end;
procedure TWorker.UpdateMemo;
begin
FMemo.Lines.Add(IntToStr(FTID) + ':' + IntToStr(FIndex));
end;
{ TDispThd }
constructor TDispThd.Create(Mone, Mtwo, Mthree: TMemo);
begin
MemoArr[0] := Mone;
MemoArr[1] := Mtwo;
MemoArr[2] := Mthree;
inherited Create(false);
end;
procedure TDispThd.Execute;
var
id, i, WaitRes: integer;
begin
FreeOnTerminate := true;
i := 0;
while true do
begin
//GetIdleMemo(id);
//TWorker.Create(i, id, MemoArr[id]);
TWorker.Create(i);
sleep(1000); //时间调短
Inc(i);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
for i := 0 to 2 do
ConnMutexUse[i] := CreateMutex(nil, FALSE, nil);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
i: integer;
begin
for i := 0 to 2 do
CloseHandle(ConnMutexUse[i]);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TDispThd.Create(memo1, Memo2, Memo3);
end;
end.
谢谢各位的帮助