【发布时间】:2013-04-25 20:23:54
【问题描述】:
我有 100 个记录类型的静态数组:
TMy_Array:array[1..100] of T;
其中 T 是:
T = record
A: double;
B: Date;
C: String;
end;
我有n 类似的线程在修改TMy_Array 中的元素
TMy_Array[n].A;
TMy_Array[n].B;
TMy_Array[n].C)`.
N 接近于100。
我还有 10 个其他线程可以选择性地修改任何字段 TMy_Array。
为了安全地实现这一点,我应该使用关键部分吗?问题来了:
是否只使用一个临界区不会导致争用和等待访问数组的线程过度拥挤?
也许我可以或应该应用 100 个关键部分来保护对 T_Array 中特定项目的访问并且不会阻塞其他线程?
Var
Cs:array [1..100] of TRTLCriticalSection;
//then for n-thread:
EnterCriticalSection(CS[n]);
TMy_Array[n].A:=…;
TMy_Array[n].B:=…;
TMy_Array[n].C:=…;
LeaveCriticalSection(CS[n]);
这是个好主意,不会使应用程序过载吗?
第二个问题:
TDateTime(真的是Double)和String 是原子数据吗?我可以读取(仅读取)它们而不用担心在另一个线程正在写入它们时发生冲突吗?
【问题讨论】:
-
你没有提到你的 Delphi 版本。后来的(D2009)版本有
TThreadList,它具有列表的内置线程锁定。我建议首先尝试这是否足以满足您的应用程序。在任何给定时间,只有一个线程可以对该列表进行操作。 -
关于原子操作。从这里引用@dThorpe:
Delphi: preferred way of protection using Critical Sections。 “如果您具有多值语义(需要在同一操作中更新多条数据)并且您的设计要求所有值始终相互一致,那么原子写入毫无意义。” -
@LURD:
TThreadList已经存在了很长时间,至少从 D5 开始,可能甚至更早。 -
@Artik:如果您需要多个线程同时访问相同
T实例,那么是的,您需要实现某种锁定机制。整个阵列的单个锁可能是一个瓶颈,但每个T上的锁也可能是矫枉过正。这实际上取决于您实际尝试使用线程来完成什么。 -
@RemyLebeau,很可能就是这样。我只看到它位于
Generics.Collections中,但现在我看到它也在System.Classes中。很抱歉造成混乱。
标签: delphi thread-safety critical-section