- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我必须在 Delphi XE7 中编写一个 DLL。我想在 DLL 中使用 TParallel.For。 DLL 被加载到 C++ 应用程序中,一切正常。但是,当应用程序终止或调用 FreeLibrary 时,应用程序会挂起。如果我删除所有 TParallel.For 循环并将它们替换为标准循环,应用程序将正常退出。
TParallel.For 循环非常简单:
TParallel.For(0, inImage.Height -1,
Procedure(ty : integer)
begin
SomeProcedure(ty);
end);
如果我使用完全相同的代码创建一个 Delphi 应用程序,一切都会完美无缺。
经过大量研究和调试后,似乎有一个死锁阻止了 C++ 应用程序在调用 FreeLibrary 时退出,但我找不到 TParallel 中的问题所在。
总结一下情况:
我的问题是:
有没有其他人经历过这种行为?
在这种情况下找到死锁的好的调试策略是什么?
非常感谢任何建议。
更新
好的,所以如果你想要最小的、完整的和可验证的例子,给你(谢谢 Stephen Ball):
library ADelphiDLL;
uses
System.SysUtils, System.Classes, Threading, SyncObjs;
function IsPrime (N: Integer): Boolean;
var
Test: Integer;
begin
IsPrime := True;
for Test := 2 to N - 1 do
if (N mod Test) = 0 then
begin
IsPrime := False;
break; {jump out of the for loop}
end;
end;
function Prime(Max : integer) : boolean;
var
tot : integer;
begin
tot := 0;
TParallel.For(1, Max, procedure (I: Integer)
begin
if IsPrime (I) then
TInterlocked.Increment (Tot);
end);
return true;
end;
exports Prime;
begin
IsMultiThread := True;
end.
在 C++ 中:
#include "stdafx.h"
typedef bool(__stdcall *primesf)(int);
void main()
{
HINSTANCE hGetDLL = LoadLibrary(L"ADelphiDLL.dll");
primesf primes = (primesf)GetProcAddress(hGetProcIDDLL, "Primes");
bool result = primes(100);
FreeLibrary(hGetDLL);// <-- Hangs here forever
}
针对非常“有帮助”的评论,“代码中存在缺陷”和“自己调试”,谢谢,这是我已经做了很长时间的事情。因此,如果这里没有任何帮助,我将尝试获得切换到 OTL 的许可,它在相关 DLL 中确实有效。
更新 2
OTL 完全按照预期工作。所以,是的,有一个“代码缺陷”。我放弃。我会建议完全放弃 Delphi,然后我们可以将所有内容转移到 C++ 和 C#。这必须是一个更好的短期(和长期)解决方案。
最佳答案
虽然我使用的是 Delphi 10.0 Seattle 和加载 Delphi DLL 的 Delphi EXE,但我看到了与此类似的问题。
无论如何,我想出的解决方案如下:
在您的 Delphi DLL 中,首先创建您自己的线程池。
使用 TParallel 的重载版本。For 将线程池对象作为其最后一个参数,并提供您自己的线程池对象。
在卸载您的 Delphi DLL 之前,确保释放您的线程池对象。
这种方法解决了我的问题。
TParallel.For documentation:
http://docwiki.embarcadero.com/Libraries/Berlin/en/System.Threading.TParallel.For
示例伪代码:
MyPool: TThreadPool;
MyPool := TThreadPool.Create;
TParallel.For(1, Max, procedure (I: Integer)
begin
if IsPrime (I) then
TInterlocked.Increment (Tot);
end,
MyPool
);
MyPool.Free;
关于c++ - 调用 FreeLibrary 时可能出现死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43536523/
我有类似下面的代码: ... id: myComponent signal updateState() property variant modelList: [] Repeater { mo
我正在处理一些我无法展示的私有(private)代码,但我已经制作了一些示例代码来描述我的问题: 主.c: #include #include #include #include typede
这个问题在这里已经有了答案: 关闭10 年前。 Possible Duplicate: what are the differences in die() and exit() in PHP? 我想
在编写 Perl 模块时,在模块内部使用 croak/die 是一个好习惯吗? 毕竟,如果调用者不使用 eval block ,模块可能会使调用它的程序崩溃。 在这些情况下,最佳做法是什么? 最佳答案
我有一些搜索线程正在存储结果。我知道当线程启动时,JVM native 代码会代理在操作系统上创建新 native 线程的请求。这需要 JVM 之外的一些内存。当线程终止并且我保留对它的引用并将其用作
我刚刚花了很多时间调试一个我追溯到 wantarray() 的问题。 .我已将其提炼为这个测试用例。 (忽略 $! 在这种情况下不会有任何有用信息的事实)。我想知道为什么wantarray在第二个示例
我看到一些代码是这样做的: if(something){ echo 'exit from program'; die; } ...more code 和其他只使用 die 的人: if
我正在尝试将此表格用于: 如果任何 $_POST 变量等于任何其他 $_POST 变量抛出错误。 如果只有几个,那不是问题,但我有大约 20 个左右所以如果我想这样做,我将不得不像这样 但这
每次我运行: hadoop dfsadmin -report 我得到以下输出: Configured Capacity: 0 (0 KB) Present Capacity: 0 (0 KB) DFS
我是一名优秀的程序员,十分优秀!