我有一个多线程Delphi程序,创建了一些类的多个实例,我希望每个类实例都有自己的TMultiReadExclusiveWriteSynchronizer实例,用于特定属性的get和set方法。
E.g。这是我在一个类中使用TMultiReadExclusiveWriteSynchronizer的单元的一部分:
interface
TSGThread=class(TThread)
private
fWaiting:boolean;
function getWaiting:boolean;
procedure setWaiting(value:boolean);
public
property waiting:boolean read getWaiting write setWaiting;
end;
implementation
var syncWaiting:TMultiReadExclusiveWriteSynchronizer;
function TSGThread.getWaiting:boolean;
begin
syncWaiting.BeginRead;
result:=fWaiting;
syncWaiting.EndRead;
end;
procedure TSGThread.setWaiting(value:boolean);
begin
syncWaiting.BeginWrite;
fWaiting:=value;
syncWaiting.EndWrite;
end;
initialization
syncWaiting:=TMultiReadExclusiveWriteSynchronizer.Create;
finalization
syncWaiting.Free;
end.
这个问题是该单元创建了一个TMultiReadExclusiveWriteSynchronizer实例,然后由多个TSGThread实例使用。
同步器仅控制对TSGThread的私有字段的访问
线程A可以使用公共属性修改线程B中的字段,因此需要同步器,但每个线程中应该有一个单独的同步器,因此如果线程修改自己的线程,则线程不必彼此等待属性。
Delphi帮助说“创建TMultiReadExclusiveWriteSynchronizer的全局实例”,但它是否必须始终是全局的? 如果一个类仅保护对其自己的属性的访问,那么同步是否会与私有字段中的TMultiReadExclusiveWriteSynchronizer实例一起使用?
答案 0 :(得分:4)
The help说:
创建与您要保护的全局内存关联的
TMultiReadExclusiveWriteSynchronizer
的全局实例。
但是你没有全局内存。您具有特定于线程对象的内存,因此为每个线程对象创建同步对象。您可以根据需要创建任意数量的内容。为您希望单独访问和保护的每个共享元素创建一个。
答案 1 :(得分:3)
这有点偏离主题,但在你给出的例子中,同步器几乎没用。无法在线程上下文切换上部分读取/写入布尔值。
另外,使用您的示例,代码如下
sgThread.Waiting := not sgThread.Waiting;
可能失败。
现在,回到主题。 TMultiReadExclusiveWriteSynchronizer的范围需要与它保护的资源一样大。由于您要保护对象的私有字段,因此您也可以将TMultiReadExclusiveWriteSynchronizer声明为私有字段。 (您正在保护对私有字段的访问权限,而不是对该属性的访问权限)
答案 2 :(得分:2)
它不是全球性的必要条件。为了保持线程安全,每次访问同步器都需要 。一种简单的方法是通过使同步器成为全局变量,但还有其他方法可以处理它。