【问题标题】:How can I prevent deadlocks in ApplicationRecoveryCallback()?如何防止 Application RecoveryCallback() 中的死锁?
【发布时间】:2012-08-30 11:43:16
【问题描述】:

我已经为ARR 注册了我的申请。假设我的应用程序有一个IdTCPServer,它使用VSPE 从串行端口读取数据并将其添加到ClientDataSet。如果主线程冻结,ARR 将调用我的 ApplicationRecoveryCallback()。我可以安全地访问恢复回调函数中的IdTCPServer吗?我希望它停止,以便在重新启动之前将我的ClientDataSet 保存到磁盘。我可以这样简单地编写我的函数吗?

function RecoveryFunction(pvParameter: Pointer): DWORD; stdcall;
var
  ContinueRecovery: Boolean;
begin
  Result := 0; // happy compiler ;-)
  repeat
    ApplicationRecoveryInProgress(ContinueRecovery);
    if not ContinueRecovery then
      ApplicationRecoveryFinished(False);
  until frmInstrument.CriticalSection.TryEnter;
  frmInstrument.IdTCPServer.Active := False;
  frmInstrument.CDS.SaveToFile(RecoveryFile);
  ApplicationRecoveryFinished(True);
end;

【问题讨论】:

  • 你为什么不首先停止应用程序冻结?
  • @DavidHeffernan 好问题,但这是保存宝贵数据的最后努力如果我的应用程序将死。我从串口采集的数据来自一堆没有内存的医学实验室仪器,所以当我收到一个数据包时,我应该用生命来保护它,可以这么说。
  • 您通过立即将其写入磁盘来保护它。当你这样做时,不需要恢复,因为你已经保存了所有可用的东西。 ARR 文档正是这样建议的。
  • @DavidHeffernan 我已经在处理数据后立即保存了数据。但在某些情况下,尤其是一些旧的“伽马计数器”,仪器发送数据包的速度远远超过我的应用程序可以处理的速度。我的缓冲区中有数据需要写入,我的数据库服务器正在花时间响应我的最后一个查询。我想保存任何尚未保存的内容以防崩溃。

标签: multithreading delphi winapi indy


【解决方案1】:

我不会那样写的。当您的程序停止响应时调用此函数。如您所知,它已停止响应,因为其他东西已经卡在等待相同的关键部分。

如果您希望即使在程序挂起时也能访问您的数据,那么您需要一种无锁方式来检测何时允许您读取数据。使用事务日志模型。以原子方式更新指示您的数据有多少是有效的。当您进入恢复功能时,读取该值,并尽可能多地保存它所说的可用。不要费心阅读超出这一点的内容,因为您无法确定它是否已损坏以及程序崩溃的原因。

【讨论】:

  • 能否在恢复回调函数中访问VCL类?我的表单、数据模块等?
  • 当然。为什么不?这都是你程序的一部分。但是,访问可能不可靠,因为您的程序已经挂起或崩溃。
  • 我的意思是如果可能存在访问冲突。例如,在访问任何数据之前,我需要强制停止所有正在运行的线程。
  • 是的,可能存在访问冲突。可能有任何东西;你不知道为什么你的程序崩溃了。不要打扰终止线程,除非它们真的阻碍了对您需要拯救的数据的访问。您的应用程序恢复功能应该做到绝对最低要求。你必须假设你所做的任何事情都可能导致你的恢复功能失败,所以不要碰任何不必要的东西。
【解决方案2】:

如果您将串行端口和 CDS 逻辑移出主线程,则可以降低您的应用程序变得无响应和 ARR 启动的可能性。主线程应该只用于 UI 逻辑,需要一段时间才能运行的业务逻辑最好在工作线程中提供。

【讨论】:

  • 我的CDS逻辑在IdTCPServerExecute,我使用VSPE将串口路由到TCP,所以我的主线程只用于UI
  • “我的主线程仅用于 UI” - 如果这是真的,那么您的应用就不会冻结。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-27
  • 1970-01-01
  • 2019-08-14
  • 1970-01-01
相关资源
最近更新 更多