将锁定在 while 循环中使变量不可读
Will lock in while loop make variable unreadable
考虑以下在线程 B 中运行的代码(即在该线程中运行的所有代码):
private void KeepValueCurrent(WaitHandle mre)
{
while (mre.WaitOne(50))
{
var newAddressOffset = LengthOfLastLogEntry;
if (newAddressOffset > _currentAddressOffset)
{
//Only update if new value is larger than existing
lock(_locker) {_currentAddressOffset = newAddressOffset;}
}
}
}
我能否访问线程 A 中的 _currentAddressOffset
,如下所示,或者锁是否会阻止我,因为线程 B 中的循环运行得如此之快?我的程序还有很多其他的依赖,所以一直没能自己测试。
lock (_locker) { currentAddressOffset = _currentAddressOffset; }
注意: _currentAddressOffset
是一个全局 int 变量,带有修饰符 volatile
以避免任何编译器优化。
更新:后续问题
从收到的答案中可以明显看出,如果我写入 _currentAddressOffset
的唯一位置是在线程 B 的循环中,我不需要围绕 int 进行锁定。但是,如果在线程中怎么办? A 我也写入那个变量。然后竞争条件的概念出现了,我将把线程 B 中的 while 循环更改为:
private void KeepValueCurrent(WaitHandle mre)
{
while (mre.WaitOne(50))
{
var newAddressOffset = LengthOfLastLogEntry;
lock(_locker)
{
if (newAddressOffset > _currentAddressOffset)
{
//Only update if new value is larger than existing
_currentAddressOffset = newAddressOffset;
}
}
}
}
在线程A中,我现在将这样读写:
lock (_locker) { currentAddressOffset = _currentAddressOffset; } //Read
lock (_locker) { _currentAddressOffset = newValue; } //Write
这种情况下是否需要锁来避免竞争条件?
非常感谢。
对 int
的赋值已经是原子的,而且它的 volatile
内存屏障已经就位。 lock
实际上什么也没做。
考虑以下在线程 B 中运行的代码(即在该线程中运行的所有代码):
private void KeepValueCurrent(WaitHandle mre)
{
while (mre.WaitOne(50))
{
var newAddressOffset = LengthOfLastLogEntry;
if (newAddressOffset > _currentAddressOffset)
{
//Only update if new value is larger than existing
lock(_locker) {_currentAddressOffset = newAddressOffset;}
}
}
}
我能否访问线程 A 中的 _currentAddressOffset
,如下所示,或者锁是否会阻止我,因为线程 B 中的循环运行得如此之快?我的程序还有很多其他的依赖,所以一直没能自己测试。
lock (_locker) { currentAddressOffset = _currentAddressOffset; }
注意: _currentAddressOffset
是一个全局 int 变量,带有修饰符 volatile
以避免任何编译器优化。
更新:后续问题
从收到的答案中可以明显看出,如果我写入 _currentAddressOffset
的唯一位置是在线程 B 的循环中,我不需要围绕 int 进行锁定。但是,如果在线程中怎么办? A 我也写入那个变量。然后竞争条件的概念出现了,我将把线程 B 中的 while 循环更改为:
private void KeepValueCurrent(WaitHandle mre)
{
while (mre.WaitOne(50))
{
var newAddressOffset = LengthOfLastLogEntry;
lock(_locker)
{
if (newAddressOffset > _currentAddressOffset)
{
//Only update if new value is larger than existing
_currentAddressOffset = newAddressOffset;
}
}
}
}
在线程A中,我现在将这样读写:
lock (_locker) { currentAddressOffset = _currentAddressOffset; } //Read
lock (_locker) { _currentAddressOffset = newValue; } //Write
这种情况下是否需要锁来避免竞争条件?
非常感谢。
对 int
的赋值已经是原子的,而且它的 volatile
内存屏障已经就位。 lock
实际上什么也没做。