我的应用程序过去是单线程的,但现在为了提高性能,我们需要使它成为多线程的。
我们有以下架构中的Lists和ListItems:
TBListItem = class(TBusinessObjects)
private
FList : TBList;
protected
//methods
public
constructor Create(AList: TBList); reintroduce;
//other methods
//properties...
end;
我们更喜欢列表的组合,而不是继承。
TBList = class(TPersistent)
private
FItemClass : TBListItemClass; //class of TBListItem
//this is used to AddObject(key, object) of the TStringList duplicates are no allowed
function BuildKey(ArrayOfKeys: array of Variant): string;
protected
//we use a stringlist to save the items
FList: TStringList;
function GetItem(Index: Integer): TBListItem;
//methods like Load(); Unload(); Save();
public
constructor Create(ARefClassItem: TBListItemClass); reintroduce;
//these methods use buildkey
function Add(ArrayOfKeys: Array of Variant): TBListItem; reintroduce;
function FindByKey(const ArrayOfKeys: array of Variant): TBListItem;
//other methods
//properties...
end;
在ADD()方法中执行以下操作:
var Index: Integer;
begin
Index:= FList.IndexOf(BuildKey(ArrayOfKeys));
if Index <> -1 then
Result:= TBListItem(FList.Objects[Index])
else
begin
Result:= FListItemClass.Create(Self);
Result.FCodigo:= ArrayOfKeys;
//load data from database.
FList.AddObject(BuildKey(ArrayOfKeys), Result)
end;
end;
正如我所说,这些对象用于在运行时记录缓存数据,但每次我们需要在其中读取/写入对象时,我们都必须:
EnterCriticalSection(instance of TRTLCriticalSection);
//Do Stuff
LeaveCriticalSection(Same instance);
我不能对架构做太大的更改,因为有继承自它的不连续类
当我运行进程时,处理器图形中有很多尖峰,也有很多停机时间
该系统由Delphi6编译器编译而成
关键会话已在单元初始化过程中创建
有别的办法吗
我至少可以不把读数锁住吗?
另外,我必须保证完整性,不允许2个对象使用相同的密钥。
您需要在读取时执行一些同步操作。你不能让一个线程在另一个线程试图读取数据结构时对其进行变异。一种常见的方法是单写多读锁定。
Delphi提供了其中一个,即TMultiReadExclusiveWriteSynchronizer
。然而,我认为它的性能很差,而且自从TMonitor
崩溃以来,我个人对Emba的工程师编写正确同步原语的能力几乎没有信心。
我的建议是使用Vista中引入的Slim读写器(SRW)锁。如果你仍然需要支持XP,那么我建议回到关键部分。