线程安全测试/递减
Threadsafe test / decrement
这段代码是线程安全的吗,或者 FCount 是否可以在执行 InterLockedDecrement 之前被另一个线程更改?
procedure TMyObject.Wait;
begin
if FCount > 0 then
InterLockedDecrement(FCount);
..
end;
代码不是线程安全的。在 if
语句中读取 FCount
存在竞争。
因为我不知道你的代码想要实现什么,更大的目标是什么,所以我不会提出解决方案。
它不是线程安全的。
- 线程 1 读取 FCount=1,评估条件为真。
- 线程 2 读取 FCount=1,评估条件为真。
- 线程 1 将 FCount 减为 0
- 线程 2 将 FCount 递减为 -1
但我假设该代码专门用于防止将 FCount
减少到零以下。
您可能需要考虑以下内容:
if InterlockedDecrement(FCount) < 0 then
InterlockedIncrement(FCount);
这样,两个并发线程中的一个将值减为-1,然后"fix its mistake"。
但是,它确实有 FCount
可能暂时 < 0
.
的副作用
正如其他人指出的那样,它不是线程安全的。如果你想确保代码减少 FCount 的值,如果它大于 0 那么你可以使用这样的东西而不锁定:
procedure TMyObject.Wait;
var
count: Integer;
countPlus1: Integer;
begin
repeat
count := FCount;
if (count > 0) then
begin
countPlus1 := count;
Dec(count);
end;
until (count <= 0) or (InterlockedCompareExchange(FCount, count, countPlus1) = countPlus1);
..
end;
这段代码是线程安全的吗,或者 FCount 是否可以在执行 InterLockedDecrement 之前被另一个线程更改?
procedure TMyObject.Wait;
begin
if FCount > 0 then
InterLockedDecrement(FCount);
..
end;
代码不是线程安全的。在 if
语句中读取 FCount
存在竞争。
因为我不知道你的代码想要实现什么,更大的目标是什么,所以我不会提出解决方案。
它不是线程安全的。
- 线程 1 读取 FCount=1,评估条件为真。
- 线程 2 读取 FCount=1,评估条件为真。
- 线程 1 将 FCount 减为 0
- 线程 2 将 FCount 递减为 -1
但我假设该代码专门用于防止将 FCount
减少到零以下。
您可能需要考虑以下内容:
if InterlockedDecrement(FCount) < 0 then
InterlockedIncrement(FCount);
这样,两个并发线程中的一个将值减为-1,然后"fix its mistake"。
但是,它确实有 FCount
可能暂时 < 0
.
正如其他人指出的那样,它不是线程安全的。如果你想确保代码减少 FCount 的值,如果它大于 0 那么你可以使用这样的东西而不锁定:
procedure TMyObject.Wait;
var
count: Integer;
countPlus1: Integer;
begin
repeat
count := FCount;
if (count > 0) then
begin
countPlus1 := count;
Dec(count);
end;
until (count <= 0) or (InterlockedCompareExchange(FCount, count, countPlus1) = countPlus1);
..
end;