如何在Delphi中原子地设置布尔值?

3

AtomicExchange要求一个Integer或NativeInt变量,但是我如何使用它(或类似的东西)以线程安全的方式设置布尔值 - 或者是否有这样的需要?


这要看你想做什么。如果你想要切换值,那么你需要使用 AtomicXXX 函数之一,并且需要使用 32 位布尔值。但是,如果你只想将值设置为特定值,而没有读取操作,那么可以直接使用简单的赋值语句实现。 - David Heffernan
1
一个Boolean是一个单字节。对于简单的只读和只写操作,直接访问变量并让系统处理原子访问即可,没有必要手动使用原子API访问Boolean。仅当您需要一起执行多个操作(先读后写、先写后读)时,才需要协调原子访问以确保值的完整性。然而,单字节数据类型没有原子API。您可以使用同步对象(如TCriticalSectionTMutexTMREWSync等)来代替。 - Remy Lebeau
2
@Remy 在一个32位类型上使用原子操作更加高效。 - David Heffernan
好的,谢谢。我只是想确保值的安全更改,以防多个远程客户端从不同的线程尝试进行更改。所以我猜我可以相信字节值本身是安全的。因此我不确定布尔类型的大小,但既然它只是字节,那就没问题了。 - Jouni Aro
1个回答

5

Delphi中的Boolean是一个字节值,不能与原子API一起使用,因为它们是基于32位值操作的。

您可以改用BOOL,它是一个32位布尔值,如下所示:

var
  b: bool;
begin
  b := False;

  // true
  AtomicIncrement(Integer(b));

  // false
  AtomicDecrement(Integer(b));

然而,增加值的操作有一定的风险,因为如果将其增加两次(类似于两次赋值为True)并减少一次,则该值仍然是True,且大于0。

另一个替代方案可能是:

  // false
  AtomicExchange(Integer(b), Integer(False));

  // true
  AtomicExchange(Integer(b), Integer(True));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接