我在模拟器中工作,用于测试发送到服务器的连接和命令。模拟器有一些计数器,如发送命令总数,成功发送命令,失败发送命令,连接尝试,连接成功等...
我使用的代码如下:
procedure TALClient.SendCommand;
begin
Try
dlgMain.IncrementIntConx; //Increments conn attemps
FTCP.Connect(1000);
If FTCP.Connected Then
Begin
dlgMain.IncrementConections; //increments successfully connections
try
dlgMain.IncrementIntSendCommand; //Increments command sent attemps (A)
FTCP.SendCmd(FCmd.FNemo + ' ' + FCmd.FParams); // (Z)
dlgMain.IncrementSendComm; //Increments sent Commands (B)
try
FParent.CS.Acquire;
FParent.FStatistic[Tag, FCmd.FTag].LastCodeResult := FTCP.LastCmdResult.NumericCode;
FParent.FStatistic[Tag, FCmd.FTag].LastMsgResult := FTCP.LastCmdResult.Text.Text;
FParent.CS.Release;
if ((FTCP.LastCmdResult.NumericCode) = (497)) then
Synchronize(UpdateCorrectCounters) //increments successfully responds from server
else
Synchronize(UpdateErrorCounters); //increments failed responds from server
except
Synchronize(UpdateErrorCounters);
end;
except
dlgMain.IncrementFailCommand; //increments failed commands (C)
end;
End
Else
Synchronize(UpdateErrorCounters); //Increment failed responses from sever
Finally
If FTCP.Connected Then
FTCP.Disconnect;
End
end;
我已经将代码更改为许多其他方式,但它永远不会正常工作。 最大的问题是发送命令的总数不等于成功发送的命令加上失败的发送命令。 (在代码中:A不等于B加C)。在标记为(Z)的行中,我从未“看到过”的回复,可能是“丢失”的回复......
那么,我做错了什么?
答案 0 :(得分:1)
我猜你正在为你的模拟器使用多个线程。这看起来像是经典的 Lost Updates 问题。您必须同步反向递增代码。
增加变量 NOT 线程安全:
Temp := CounterValue;
// If another thread intercepts here, we've got a lost update
Temp := Temp + 1;
CounterValue := Temp;
请参阅此MSDN article以阅读有关并发问题的更多信息。
答案 1 :(得分:1)
如果您只使用计数,则可以使用Windows函数InterlockedIncrement
和InterlockedDecrement
,并且不需要任何锁定。