'boolean'变量是否可以从任何线程读取和写入线程安全?我已经看到一些新闻组的引用说它们是.是否有其他数据类型?(列举的类型,也可能是短的内容?)
有一个可以安全地从任何线程和另一个列表中读取的所有数据类型的列表将是很好的,这些列表也可以安全地写入任何线程,而不必求助于各种同步方法.
请注意,您可以使用delphi中的所有内容进行unthreadsafe.而其他人则提到布尔值上的对齐问题,这在某种程度上隐藏了真正的问题.
是的,您可以在任何线程中读取布尔值,并在任何线程中写入布尔值,如果它正确对齐的话.但是从你改变的布尔值中读取并不一定是"线程安全的".假设您有一个布尔值,当您更新一个数字时,您将其设置为true,以便另一个线程读取该数字.
if NumberUpdated then begin LocalNumber = TheNumber; end;
由于优化,处理器使得可以在读取NumberUpdated之前读取TheNumber,因此在最后更新NumberUpdated时,您可能会获得TheNumber的旧值.
Aka,您的代码可能会变成:
temp = TheNumber; if NumberUpdated the begin LocalNumber = temp; end;
Imho,一个基本的经验法则:
"读取是线程安全的.写入不是线程安全的."
因此,如果您要进行写操作,请保护数据,并在任何地方同步读取值,同时可能会发生写入操作.
另一方面,如果您只在一个线程中读取和写入值,那么它的线程安全.因此,您可以在临时位置执行大量写入操作,然后同步应用程序范围数据的更新.
奖金模糊:
VCL不是线程安全的.在主线程中保留ui内容的所有修改.继续在主线程中创建所有ui内容.
许多函数也不是线程安全的,而其他函数则通常取决于底层的winapi调用.
我不认为"列表"会有所帮助,因为"线程安全"可能意味着很多东西.
这不是数据类型是线程安全的问题,但它是你用它们做什么的问题.没有锁定没有操作是线程安全的,涉及加载一个值,然后更改它,然后将其写回:递增或递减一个数字,清除或设置一个集合中的元素 - 它们都不是线程安全的.
有许多功能允许原子操作:互锁增量,互锁减量和互锁交换.这是一个常见的概念,没有特定于Windows,x86或Delphi.对于Delphi,您可以使用Windows API的InterlockedFoo()函数,这些函数也有几个包装器.或者自己写.这些函数对整数进行操作,因此您可以对它们进行原子递增,递减和整数交换(32位).
您还可以使用带有锁前缀的汇编程序和前缀ops.
有关更多信息,请参阅此StackOverflow问题.
在32位架构上,只有正确对齐的32位或更少数据类型才应被视为原子级.32位值必须是4对齐的(数据的地址必须可以被4整除).您可能不会在如此严格的级别上遇到交错,但理论上您可以使用双重,Int64或扩展非原子写入.