【问题标题】:parallel.async, pass parameters thread-safeparallel.async,传递参数线程安全
【发布时间】:2020-09-01 04:44:03
【问题描述】:

看看这个(伪)代码

procedure TestASync;
begin
  var lSomeIntf:=TSomeImplementor.Create as ISomeIntf;
  parallel.ASync(
    procedure
    begin
       sleep(1000); // allow the main thread to finish
       MyThreadedProc(lSomeIntf);
    end
  );
  sleep(100); // will finish before sub-thread
end;

这会产生一个竞争条件,因为我发现很难。因为在匿名方法有机会调用MyThreadedPorc 之前,TestASync 已经完成,所以使用nil 接口调用MyThreadedProc。 (这已经比一些随机值好很多了)

Q1:对于简单的非引用计数变量(如整数、双精度等)是否也是如此 - 我强烈怀疑它们可能会更改/返回随机值,因为它们位于在堆栈上。

Q2:如何以简单、干净的方式解决这个问题?

我一直在摆弄IOmniTask 接口和其他方法来启动类似的不受监控的后台线程,但所有这些似乎都使我的代码变得混乱并使源代码难以理解。

也许是这样的? :

procedure TestGenericASync;
begin
  var lSomeIntf:=TSomeImplementor.Create as ISomeIntf;
  parallel.ASync<ISomeIntf>(lSomeIntf,
    procedure (const aSomeIntf:ISomeIntf)
    begin
       MyThreadedProc(aSomeIntf);
    end
  );
end;


【问题讨论】:

  • 您的原始代码应该可以工作。捕获内联变量或直接使用该变量作为参数可能存在问题。我会尝试删除内联变量声明并使用常规局部变量,如果这不起作用,则在 Async proc 中声明局部变量并在将其用作参数之前为其分配 lSomeIntf。目前无法测试以了解实际情况。
  • 在调用 MyThreadedProc 之前将其分配给匿名过程中的局部变量无效。在匿名程序开始时设置断点,lSOmeIntf 已经为零。 (可能取决于 CPU、速度和随机性。
  • @DalijaPrasnikar 是正确的。 anon 方法由一个类实现,该类引用接口(捕获)并应使其保持活动状态。
  • 捕获内联变量有一个错误quality.embarcadero.com/browse/RSP-26666 删除内联变量声明应该可以工作(刚刚检查过),如果没有,那么我们需要查看minimal reproducible example
  • 没有竞争条件。在 TestAsync 完成之前捕获变量(这意味着额外增加引用计数)并减少局部变量引用计数。如果您有一些问题,它们不是由于您在此处提供的捕获和代码造成的。

标签: multithreading delphi omnithreadlibrary


【解决方案1】:

正如Dalija 建议的那样,您必须使用内联变量声明来解决Delphi bug (RSP-26666)。这些内联变量声明没有被匿名方法正确捕获。

解决方法是不使用内联变量。 (或升级到 RS 10.4 Sydney。)

procedure TestASync;
var lSomeIntf:ISomeIntf; // declaring here works around the bug
begin
  lSomeIntf:=TSomeImplementor.Create as ISomeIntf;
  parallel.ASync(
    procedure
    begin
       sleep(1000); // allow the main thread to finish
       MyThreadedProc(lSomeIntf);
    end
  );
  sleep(100); // will finish before sub-thread
end;

【讨论】:

  • RS10.4 Sydney似乎已经修复了这个bug
  • 在 10.4 sydney 中创建了一个新的、类似的错误。引用计数会随着捕获而增加,但不会在接口超出范围时被子线程减少。
  • 我已经把密切相关的接口发布bug放在这里:quality.embarcadero.com/browse/RSP-29564请投票给这个bug!
猜你喜欢
  • 1970-01-01
  • 2013-05-11
  • 2016-05-15
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 2018-04-08
  • 1970-01-01
相关资源
最近更新 更多