类实例“拥有”TMultiReadExclusiveWriteSynchronizer实例?

时间:2011-05-08 03:12:53

标签: multithreading delphi synchronization

我有一个多线程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实例一起使用?

3 个答案:

答案 0 :(得分:4)

The help说:

  

创建与您要保护的全局内存关联的TMultiReadExclusiveWriteSynchronizer的全局实例。

但是你没有全局内存。您具有特定于线程对象的内存,因此为每个线程对象创建同步对象。您可以根据需要创建任意数量的内容。为您希望单独访问和保护的每个共享元素创建一个。

答案 1 :(得分:3)

这有点偏离主题,但在你给出的例子中,同步器几乎没用。无法在线程上下文切换上部分读取/写入布尔值。

另外,使用您的示例,代码如下

sgThread.Waiting := not sgThread.Waiting;

可能失败。

现在,回到主题。 TMultiReadExclusiveWriteSynchronizer的范围需要与它保护的资源一样大。由于您要保护对象的私有字段,因此您也可以将TMultiReadExclusiveWriteSynchronizer声明为私有字段。 (您正在保护对私有字段的访问权限,而不是对该属性的访问权限)

答案 2 :(得分:2)

它不是全球性的必要条件。为了保持线程安全,每次访问同步器都需要 。一种简单的方法是通过使同步器成为全局变量,但还有其他方法可以处理它。