此代码线程是否安全,或者在执行InterLockedDecrement之前是否可以通过另一个线程更改FCount?
procedure TMyObject.Wait;
begin
if FCount > 0 then
InterLockedDecrement(FCount);
..
end;
答案 0 :(得分:5)
代码不是线程安全的。 writeDisposition
声明中的FCount
读取比赛。
由于我不知道您的代码要实现的目标,更大的目标是什么,我不会建议解决方案。
答案 1 :(得分:5)
这不是线程安全的。
但我认为该代码专门用于防止将FCount
降低到零以下。
您可能需要考虑以下内容:
if InterlockedDecrement(FCount) < 0 then
InterlockedIncrement(FCount);
这样,两个并发线程中的一个会将值减小为-1,然后“修复它的错误”
但是,它确实会产生FCount
可能暂时为< 0
的副作用。
答案 2 :(得分:1)
其他人已经指出,这不是线程安全的。如果你想确保代码减少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;