线程可以安全地读取由VCL事件设置的变量吗? [英] Can threads safely read variables set by VCL events?

查看:98
本文介绍了线程可以安全地读取由VCL事件设置的变量吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

线程是否可以读取由Delphi VCL事件设置的变量?

Is it safe for a thread to READ a variable set by a Delphi VCL event?

当用户单击VCL TCheckbox时,主线程设置一个布尔值复选框的Checked状态。

When a user clicks on a VCL TCheckbox, the main thread sets a boolean to the checkbox's Checked state.

CheckboxState := CheckBox1.Checked;

任何时候,一个线程读取该变量

At any time, a thread reads that variable

if CheckBoxState then ...

如果线程错过布尔值的更改,因为线程会检查循环中的变量,因为它执行其他操作。所以它会最终看到状态的变化...

It doesn't matter if the thread "misses" a change to the boolean, because the thread checks the variable in a loop as it does other things. So it will see the state change eventually...

这是安全吗?还是需要特殊代码?围绕着变量的读写(分别在线程和主线程中)与关键代码调用必要和足够吗?

Is this safe? Or do I need special code? Is surrounding the read and write of the variable (in the thread and main thread respectively) with critical code calls necessary and sufficient?

正如我所说,没关系如果线程获得错误值,但是我一直认为如果一个线程尝试在主线程正在写入它的时候读取一个变量,那么可能会有一个低级别的问题。反之亦然。

As I said, it doesn't matter if the thread gets the "wrong" value, but I keep thinking that there might be a low-level problem if one thread tries to read a variable while the main thread is in the middle of writing it, or vice versa.

我的问题与此类似:跨线阅读变量谁的价值不被认为是重要的

My question is similar to this one: Cross thread reading of a variable who's value is not considered important.

(还与我之前的问题有关:在Thread中使用EnterCriticalSection来更新VCL标签

(Also related to my previous question: Using EnterCriticalSection in Thread to update VCL label)

推荐答案

这是安全的三个原因:


  • 只有一个线程写入变量。

  • Only one thread writes to the variable.

变量只有一个字节,所以没有办法读取不一致的值。它将被读取为 True False 。不能与Delphi c> boolean 值的对齐问题。

The variable is only one byte, so there is no way to read an inconsistent value. It will be read either as True or as False. There can't be alignment issues with Delphi boolean values.

Delphi编译器没有广泛的检查变量是否实际写入,如果不是,则不会优化任何代码。非局部变量将始终被读取,不需要 volatile 说明符。

The Delphi compiler does no extensive checks whether a variable is actually written to, and does not "optimize" away any code if not. Non-local variables will always be read, there is no need for the volatile specifier.

说完,如果你真的不确定,你可以使用一个整数值而不是布尔值,并使用 InterlockedExchange() 函数写入变量。这在这里是过分的,但是这是一个很好的技术,因为对于单机字大小的值,它可能会消除锁的需要。

Having said that, if you are really unsure about this you could use an integer value instead of the boolean, and use the InterlockedExchange() function to write to the variable. This is overkill here, but it's a good technique to know about, because for single machine word sized values it may eliminate the need for locks.

您也可以替换 boolean 通过正确的同步原语,如事件,并有线程块 - 这将有助于消除线程中的繁忙循环。

You can also replace the boolean by a proper synchronization primitive, like an event, and have the thread block on that - this would help you eliminate busy loops in the thread.

这篇关于线程可以安全地读取由VCL事件设置的变量吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆