是'布尔'变线程安全的阅读和写作,从任何线?我已经看到了一些新闻组参考文献来说,它们。任何其他数据类型可利用的?(列举的类型、短整数也许?)

这将是好的,有一个列表中的所有数据的类型,可以安全地从中读取任何线和另一份名单,也可以被安全地写到任何线而不必诉诸于各种同步的方法。

有帮助吗?

解决方案

请注意,您可以在Delphi unthreadsafe基本上应有尽有。而其他提到的方式对本布尔对准问题隐藏真正的问题。

是的,你可以阅读任何线程一个布尔值,并写入一个布尔值在任何线程,如果它的正确对齐。但是,从你改变一个布尔读的未必是“线程安全”反正。假设你有让另一个线程读取的次数,当你更新一个数字,你设置为true的布尔值。

if NumberUpdated then
begin
  LocalNumber = TheNumber;
end;

由于优化处理器使得数量写可NumberUpdated之前被读取被读取,因而可能会得到虽然你们更新NumberUpdated最后数量写的旧值。

阿卡,代码可能成为:

temp = TheNumber;
if NumberUpdated the
begin
  LocalNumber = temp;
end;

IMHO,拇指的基本规则:结果 “读是线程安全的。写操作是不是线程安全的。”结果 所以,如果你打算做一个写有同步的随处保护数据在写可能的可能发生你读的价值。结果 在另一方面,如果你只阅读和在一个线程写的值,那么它是线程安全的。所以,你可以做一个大块在一个临时位置写的,然后同步应用程序范围的数据的更新。

加成书籍说明:

在VCL不是线程安全。保持UI的东西全部修改在主线程。保留所有UI的东西创造在主线程中了。

很多功能不是线程安全的两种,有的则是,它往往依赖于底层WINAPI调用。

我不认为一个“清单”将作为“线程安全”乐于助人可能意味着很多东西。

其他提示

这是不是数据类型是线程安全的问题,但它是你与他们做什么的问题。没有锁定任何操作是线程安全的,涉及装载值,然后改变它,然后写回:递增或递减的数字,清除或一组设置元素 - 他们都不是线程安全的。

有多种功能,其允许原子操作:互锁递增,递减互锁,并互锁交换。这是一个常见的概念,没有具体到Windows,x86或德尔福。德尔福您可以使用Windows API的InterlockedFoo()函数,还有周围那些过于几个包装。或者自己写。功能对整数与他们进行操作,所以可以有原子递增,递减和的整数(32位)交换。

您还可以使用汇编器和前缀OPS与锁定前缀。

有关详情,请参阅也此的StackOverflow 问题。

在32位体系结构,只有适当地对准的32位或更少的数据类型应被视为原子。 32位值必须是4对齐(该数据的地址必须是整除四个)。你可能不会遇到在这样紧张的水平交织,但理论上你可以有双,Int64的或扩展非原子写入。

使用多核RISC处理和单独的核心高速缓存存储器中的现代处理器的混合时,它是任何琐碎的高级语言的读或写构建体(或就此而言许多一旦无长的情况下-upon-A-8086时间“原子”汇编指令)可以被认为是原子的。事实上,除非一个汇编指令被专门设计为原子,它可能不是原子 - 包括最机制的内存读取。即使在汇编级读长整型可以通过从被共享相同的存储器,并使用在RISC处理器级异步高速缓存更新操作的另一个处理器核心同时写入被损坏。请记住,包括多个RISC内核的处理器上,甚至汇编语言指令是有效地只是“更高级别”的代码指令!你永远不会真正知道如何他们正在在位级实现,它可能不是你所期望相当,如果你在读一个古老的8086(单核)汇编手册。 Windows不提供原生的系统兼容原子运营商,你会被建议使用这些,而不是做出关于原子操作的任何基础的假设。

为什么要使用Windows的运营商?由于Windows做的第一件事就是建立机器是什么,它在运行。它的一个保证的关键方面它得到正确的是什么样的原子操作有,他们是如何工作的。如果你希望你的代码在任何未来的处理器很好地工作在未来,您可以复制(不断更新)这一切的努力,在自己的代码,也可以利用这一事实的Windows做的都已经在启动。然后,它并入了必要的代码到其在运行时API。

阅读原子操作的MSDN页面。 Windows API的表面,这些给你。他们可能有时会显得笨重或笨拙 - 但它们是面向未来的,他们将永远准确地工作,因为它在锡说。

我怎么知道呢?嗯,因为如果他们没有 - 那么你就不能运行Windows。句号。没关系运行自己的代码。

当你写的代码,它始终是一个好主意,了解简约和考虑奥卡姆剃刀。换句话说,如果Windows已经这样做了,你的代码需要在Windows上运行,那么使用了什么的Windows已经这样做,而不是试图出许多替代和日益复杂的假设的解决方案,可能会或可能无法正常工作。做别的只是一个浪费你的时间(当然,除非是你是什么)。

印第码包含的一些原子/线安全的数据类型IdThreadSafe.pas:

  • TIdThreadSafeInteger
  • TIdThreadSafeBoolean
  • TIdThreadSafeString
  • TIdThreadSafeStringList 和更多一些...
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top