Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading parallel.async,传递参数线程安全_Multithreading_Delphi_Omnithreadlibrary - Fatal编程技术网

Multithreading parallel.async,传递参数线程安全

Multithreading parallel.async,传递参数线程安全,multithreading,delphi,omnithreadlibrary,Multithreading,Delphi,Omnithreadlibrary,看看这个(伪)代码 这产生了一个竞赛条件,因为我发现了艰难的道路。因为在匿名方法获得调用MyThreadedProc的机会之前,TestASync已经完成,所以使用nil接口调用MyThreadedProc。(这比一些随机值要好得多) Q1:对于简单的、非ref计数的变量(如整数、双精度等)也是如此吗?我强烈怀疑它们可能会被更改/返回随机值,因为它们位于堆栈上 Q2:我如何以简单、干净的方式解决这个问题 我一直在摆弄IOmniTask接口和其他方法来启动一个不受监控的后台线程,但所有这些似乎都会

看看这个(伪)代码

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

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

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

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

也许是这样的

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


过程TestGenericASync;
开始
var lSomeIntf:=TSomeImplementor.Create as ISomeIntf;
parallel.ASync(lSomeIntf,
过程(常量aSomeIntf:isomintf)
开始
MyThreadedProc(aSomeIntf);
结束
);
结束;
正如建议的那样,您必须使用内联变量声明来解决问题。匿名方法无法正确捕获这些内联变量声明

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


您的原始代码应该可以工作。捕获内联变量或直接使用该变量作为参数可能存在问题。我将尝试删除内联变量声明并使用常规局部变量,如果这不起作用,则在Async proc中声明局部变量并将lSomeIntf分配给该变量,然后再将其用作参数。目前无法测试以查看实际情况。在调用MyThreadedProc之前,在匿名过程中将其分配给局部变量也没有效果。在匿名过程的开始处设置断点,则lSOmeIntf已为零。(可能取决于CPU、速度和随机性。@DalijaPrasnikar是正确的。anon方法是由一个类实现的,该类引用接口(捕获)并应使其保持活动状态。捕获内联变量时存在一个错误。删除内联变量声明应能正常工作(刚刚检查)若并没有,那个么我们需要看到并没有竞争条件。变量被捕获(这意味着额外增加引用计数)在TestAsync完成和局部变量引用计数减少之前。如果您有一些问题,这些问题不是由于捕获和您在此处介绍的代码造成的。这个错误似乎已在RS10.4 sydney中修复,并在10.4 sydney中创建了一个新的类似错误。引用计数随捕获而增加,但从未减少接口超出范围时的子线程。我将密切相关的接口发布错误放在这里:请投票支持这个错误!
procedure TestGenericASync;
begin
  var lSomeIntf:=TSomeImplementor.Create as ISomeIntf;
  parallel.ASync<ISomeIntf>(lSomeIntf,
    procedure (const aSomeIntf:ISomeIntf)
    begin
       MyThreadedProc(aSomeIntf);
    end
  );
end;


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;