私はいくつかのマルチスレッド アプリケーションを使用してきましたが、その一部にはスレッド保護オブジェクトが必要です。次の方法を使用して、個々のオブジェクト スレッドの保護を停止しています。
type
TMyClass = class(TObject)
private
FLock: TRTLCriticalSection;
FSomeString: String;
procedure Lock;
procedure Unlock;
function GetSomeString: String;
procedure SetSomeString(Value: String);
public
constructor Create;
destructor Destroy; override;
property SomeString: String read GetSomeString write SetSomeString;
end;
implementation
constructor TMyClass.Create;
begin
InitializeCriticalSection(FLock);
Lock;
try
//Initialize some stuff
finally
Unlock;
end;
end;
destructor TMyClass.Destroy;
begin
Lock;
try
//Finalize some stuff
finally
Unlock;
end;
DeleteCriticalSection(FLock);
inherited Destroy;
end;
procedure TMyClass.Lock;
begin
EnterCriticalSection(FLock);
end;
procedure TMyClass.Unlock;
begin
LeaveCriticalSection(FLock);
end;
function TMyClass.GetSomeString: String;
begin
Result:= '';
Lock;
try
Result:= FSomeString;
finally
Unlock;
end;
end;
procedure TMyClass.SetSomeString(Value: String);
begin
Lock;
try
FSomeString:= Value;
finally
Unlock;
end;
end;
しかし、オブジェクトのリストを実装すると、各オブジェクトを安全に保護する方法がわかりません。次のようにオブジェクト リストを作成します。
type
TMyClass = class;
TMyClasses = class;
TMyClass = class(TObject)
private
FOwner: TMyClasses;
public
constructor Create(AOwner: TMyClasses);
destructor Destroy; override;
end;
TMyClasses = class(TObject)
private
FItems: TList;
function GetMyItem(Index: Integer): TMyItem;
public
constructor Create;
destructor Destroy; override;
procedure Clear;
function Count: Integer;
property Items[Index: Integer]: TMyClass read GetMyItem; default;
end;
implementation
{ TMyClass }
constructor TMyClass.Create(AOwner: TMyClasses);
begin
FOwner:= AOwner;
FOwner.FItems.Add(Self);
//Initialize some stuff...
end;
destructor TMyClass.Destroy;
begin
//Uninitialize some stuff...
inherited Destroy;
end;
{ TMyClasses }
constructor TMyClasses.Create;
begin
FItems:= TList.Create;
end;
destructor TMyClasses.Free;
begin
Clear;
FItems.Free;
inherited Destroy;
end;
procedure TMyClasses.Clear;
begin
while FItems.Count > 0 do begin
TMyClass(FItems[0]).Free;
FItems.Delete(0);
end;
end;
function TMyClasses.Count: Integer;
begin
Result:= FItems.Count;
end;
function TMyClasses.GetMyItem(Index: Integer): TMyClass;
begin
Result:= TMyClass(FItems[Index]);
end;
これには 2 つの方法があり、どちらの方法も信頼できません。1 つの方法は、リスト オブジェクト ( ) にクリティカル セクション ロックを実装し、その中の各オブジェクトがこのロックを共有することです ( andTMyClasses
を呼び出すことによって) 。しかし、2 つの異なるスレッドは、このリストの 2 つの異なるオブジェクトを2 番目の方法は、それぞれの個別のオブジェクトに別のクリティカル セクションを配置することですが、これらが多すぎるのも危険ですよね? どうすればリストとすべてのオブジェクトを保護できますか?一緒にリスト?FOwner.Lock;
FOwner.Unlock;