Multithreading TThread的子线程,从主线程访问属性

Multithreading TThread的子线程,从主线程访问属性,multithreading,delphi,Multithreading,Delphi,我有一个类,它是TThread的后代。我有一些只读的公共属性。如果我的主线程在线程处于活动状态时读取这些值,我会遇到问题吗?如果“只读属性”是指TThread子体本身也不会更改它们,并将它们初始化为a.s.a.p,那么不,一切都会好的(只要在请求属性值时确保线程处于活动状态并正在启动) 如果“只读属性”是指只有TThread子代会更改它们,那么您需要确保主线程在更改它们时没有读取它们(除非它们是原子值,如整数).基本类型,如整数、布尔、字符和指针,在任何时候都可以安全读取。引用类型,如字符串、接

我有一个类,它是TThread的后代。我有一些只读的公共属性。如果我的主线程在线程处于活动状态时读取这些值,我会遇到问题吗?

如果“只读属性”是指TThread子体本身也不会更改它们,并将它们初始化为a.s.a.p,那么不,一切都会好的(只要在请求属性值时确保线程处于活动状态并正在启动)


如果“只读属性”是指只有TThread子代会更改它们,那么您需要确保主线程在更改它们时没有读取它们(除非它们是原子值,如整数).

基本类型,如
整数
布尔
字符
指针
,在任何时候都可以安全读取。引用类型,如
字符串
、接口和动态数组,只有在其他线程不可能同时分配新值时才可以安全读取。请使用关键的例如,
Synchronized
方法,以确保线程在主线程读取值时没有修改该值


您还必须记住,您读取的任何值在使用时都可能已过期-线程可能在您读取它和使用它之间写入了一个新值。

这取决于属性类型,也可能取决于它们的访问器方法

type
  TMyThread = class(TThread)
  private
    FIntfield: integer;
  public
    property IntField: integer read FIntField;
  end;

访问此属性不会有问题,因为访问32位值是一个原子操作。但是,如果该属性大于32位,或者主线程访问时可能更改的类引用,则您将遇到问题。

回答完美!正是我需要的信息。我正在从TThrea内部更新值d子代,并不是所有的值都是原子的。谢谢您的回答。如果您的代码没有32位对齐,即使是“原子”值(如整数)也可能失败。Indy在Core\IdThreadSafe.pas中包含一些原子数据类型,包括IdThreadSafeInt64甚至tidThreadSafeBooleanUpdate“a.s.a.p.”这还不够。基本上只有一种方法可以安全地执行此操作,而进行初始化的方法是在主线程的上下文中执行的,即在构造函数中。一旦多个线程可以访问字段,它就不再安全了。@mghie:非常正确,我应该在这里更具体一些。或者,您可以在恢复之前,请使用TThread“createSuspended”,并从主线程触发一些初始化。虽然不太好,但我在某些场景中看到过这种情况。我相信它被称为“Synchronize”(最后没有D)