c – 调用FreeLibrary可能导致死锁

c – 调用FreeLibrary可能导致死锁,第1张

概述我必须在Delphi XE7中编写一个DLL.我想在DLL中使用TParallel.For.该DLL被加载到一个C应用程序,其中一切正常.但是,当应用程序终止或者调用FreeLibrary时,应用程序挂起.如果我删除所有的TParallel.For循环并将其替换为标准循环,则应用程序正常退出. TParallel.For循环非常简单: TParallel.For(0, inImage.Height 我必须在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应用程序,一切都可以正常工作.

经过大量的研究和调试,看起来似乎有一个死锁,这是在调用Freelibrary时阻止C应用程序退出,但是我找不到TParallel中的问题.

总结情况:

> TParallel.For循环全部完成并产生正确的结果.
>完全相同的TParallel.For在Delphi .exe中的代码工作正常.
> DLL被加载并且这些函数被调用并且在C应用程序内正确执行.
>如果没有TParallel.For循环,C应用程序将正确退出.
>如果有TParallel.For循环,C应用程序将挂起.
>我猜测当Freelibrary被调用时会发生死锁.
>如果我使用OTL线程库,一切都可以正常工作.

我的问题是:

有没有人经历过这种行为?

在这种情况下,找到一个僵局是什么好的调试策略?

任何建议非常感谢.

UPDATE

好的,所以如果你想要最小,完整和可验证的例子,这里你去(谢谢斯蒂芬·鲍尔):

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 EXE加载Delphi DLL.

无论如何,我想出的解决方案如下:

>在您的Delphi DLL中,首先创建自己的线程池.
>使用重载版本的TParallel.For它将一个线程池对象作为其最后一个参数,并提供您自己的线程池对象.
在卸载Delphi DLL之前,确保释放你的线程池对象.

这种方法解决了我的问题.

TParallel.For文档:

http://docwiki.embarcadero.com/Libraries/Berlin/en/System.Threading.TParallel.For

示例伪代码:

MyPool: TThreadPool;MyPool := TThreadPool.Create;TParallel.For(1,procedure (I: Integer)    begin      if IsPrime (I) then        TInterlocked.Increment (Tot);    end,MyPool  );MyPool.Free;
总结

以上是内存溢出为你收集整理的c – 调用FreeLibrary可能导致死锁全部内容,希望文章能够帮你解决c – 调用FreeLibrary可能导致死锁所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1253269.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存