如何解决选择性临界区-有条件的
| 我有一个将db表作为参数的线程,遇到了一个问题,即我无法同时写入该db表。 一个TMyThread实例可以有一个\'Member \'数据库表,而另一个可以有\'Staff \',但是可能会有两个线程在同一表中打开的情况。 因此,我需要将代码包装在关键部分(或类似的部分)中,但我不希望出现一些肮脏的东西,例如(fMemberTable,fStaffTable)等几个关键部分。begin
if fDBTable = \'Member\' then
fMemberTable.Enter
else if fDbTable = \'Staff\' then
....
我们有8张桌子,这样会很混乱
有什么办法可以做吗
TCricalSection(fMemberTable).Enter;
还是一些易于“缩放”和使用的方法?
该函数的一个关键部分没有意义,因为我不想保留其他表。
解决方法
你可以做:
TMonitor.Enter(fMemberTable);
try
// Do your stuff
finally TMonitor.Exit(fMemberTable);
end;
请注意,这是一个自旋锁,不是真正的关键部分。如果您不会发生很多冲突,但是如果线程有规律地互相阻塞,则非常实用,您可能希望退回到关键部分。根据定义,自旋锁是忙等待锁。
但是我不确定哪个版本的Delphi引入了此功能,并且您没有特定于版本的标签。
,您可以使用关键部分列表,例如,本单元中定义的My类:
interface
uses Classes,SyncObjs;
type
{ TCriticalSectionList by jachguate }
{ http://jachguate.wordpress.com }
TCriticalSectionList = class
private
FCSList: TThreadList;
FNameList: TStringList;
function GetByName(AName: string): TCriticalSection;
public
constructor Create();
destructor Destroy(); override;
property ByName[AName: string]: TCriticalSection read GetByName; default;
end;
function CSList: TCriticalSectionList;
implementation
uses SysUtils;
{ TCriticalSectionList }
constructor TCriticalSectionList.Create;
begin
inherited;
FCSList := TThreadList.Create;
FNameList := TStringList.Create;
end;
destructor TCriticalSectionList.Destroy;
var
I: Integer;
AList: TList;
begin
AList := FCSList.LockList;
for I := AList.Count - 1 downto 0 do
TCriticalSection(AList[I]).Free;
FCSList.Free;
FNameList.Free;
inherited;
end;
function TCriticalSectionList.GetByName(AName: string): TCriticalSection;
var
AList: TList;
AIdx: Integer;
begin
AList := FCSList.LockList;
try
AName := UpperCase(AName);
AIdx := FNameList.IndexOf(AName);
if AIdx < 0 then
begin
FNameList.Add(AName);
Result := TCriticalSection.Create;
AList.Add(Result);
end
else
Result := AList[AIdx];
finally
FCSList.UnlockList;
end;
end;
var
_CSList: TCriticalSectionList;
function CSList: TCriticalSectionList;
begin
if not Assigned(_CSList) then
_CSList := TCriticalSectionList.Create;
Result := _CSList;
end;
initialization
_CSList := nil;
finalization
_CSList.Free;
end.
该类基本上定义了一个关键部分的列表,可以通过\“ name \”来访问。首次要求使用特定名称的关键部分时,将自动为您创建关键部分。您必须使用提供的CSList函数访问此类的单个实例。
当列表的实例被销毁时,所有关键节都被销毁,例如,“ default \”实例在应用程序结束时被销毁。
您可以像以下示例一样编写代码:
begin
CSList[fDBTable].Enter;
try
DoStuff;
finally
CSList[fDBTable].Leave;
end;
end;
请享用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。