简体   繁体   English

枚举类型 - 线程安全

[英]Enumerated type - thread safety

I'm having an argue with a colleague about thread safety on enumerated types. 我和同事争论枚举类型的线程安全性。 Having the following simple enumerated type: 具有以下简单枚举类型:

type Suit = (Club, Diamond, Heart, Spade);

and declared as a variable inside a class as in the following dummy code: 并在类中声明为变量,如下面的虚拟代码:

type 
TTest = class
private 
  FSuit: Suit;
  function SetSuit(aValue: Suit);
public
  property GimmeSuit: Suit read FSuit;

.....

function SetSuit(aValue: Suit);
begin
  FSuit:= aValue;
end;

I say that this code is thread safe, as setting FSuit variable's value is an atomic operation. 我说这段代码是线程安全的,因为设置FSuit变量的值是一个原子操作。 I'm wrong? 我错了? I didn't found anything on web about this case. 关于这个案子我没有在网上找到任何东西。

The terminology you use, threadsafe and atomic need to be clarified before this can properly be addressed. 在使用术语之前,需要澄清您使用的术语, 线程安全原子 ,才能正确解决。

  • Threadsafe is a vague term that has to be qualified in terms of the specific context in which it is to be applied. Threadsafe是一个模糊的术语,必须根据其应用的特定上下文进行限定。 This is covered in great detail by Eric Lippert's classic article What is this thing you call "thread safe"? Eric Lippert的经典文章详细介绍了这一点你称之为“线程安全”的东西是什么?
  • An atomic operation is one that is indivisible. 原子操作是不可分割的操作。 It appears to the rest of the system as happening at once. 系统的其他部分似乎同时发生。

In the code you have shown I assume that multiple threads are both reading and writing FSuit . 在您显示的代码中,我假设多个线程都在读取和写入FSuit

With all that in place, reading and writing FSuit is atomic, so long as it is a single byte, or aligned. 有了这一切,读取和写入FSuit就是原子的,只要它是单个字节或对齐。

Single byte memory access is always atomic. 单字节内存访问始终是原子的。 If the enumerated type is larger than a single byte, then it must be aligned for memory read/write to be atomic. 如果枚举类型大于单个字节,则必须将内存读/写对齐为原子。 Misaligned memory access can tear . 未对齐的内存访问可能会撕裂 That is, the reading thread may see only part of the write because the variable straddles a cache line. 也就是说,读取线程可能只看到写入的一部分,因为该变量跨越了高速缓存行。 The writing thread has to write part of the variable to one cache line, and then the rest to the adjacent cache line, and the reading thread might read the entire variable part way through the two stage write process. 写入线程必须将变量的一部分写入一个高速缓存行,然后将其余部分写入相邻的高速缓存行,并且读取线程可以通过两阶段写入过程部分地读取整个变量。

Now, with default settings, this enumerated type will be a single byte, and the class layout will be aligned. 现在,使用默认设置,此枚举类型将是单个字节,并且类布局将对齐。 So even read/write to larger enumerated types would be atomic. 因此,即使对较大的枚举类型进行读/写也是原子的。

As for whether or not your program is threadsafe, that cannot be determined from the information here. 至于你的程序是否是线程安全的,这不能从这里的信息确定。 You would need to clarify what the intent was. 你需要澄清意图是什么。 For example, suppose that two threads wrote to FSuit , and a third thread read from it. 例如,假设两个线程写入FSuit ,第三个线程从中读取。 If your program's correctness does not depend about the orderings of those memory accesses, then it is threadsafe. 如果程序的正确性不依赖于那些内存访问的顺序,那么它就是线程安全的。 If its correctness does depend on the ordering, then it is not threadsafe and requires synchronisation. 如果它的正确性取决于排序,则它不是线程安全的并且需要同步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM