我有一个Delphi代码,它调用一个DLL。动态链接DLL。
在我的代码开始时,我通过
DllHandle:= LoadLibrary(DllFileName);DLLHandle=0,这是很好的。我可以转到主程序的下一行。non-zero DLLHandle,这也是很好的。但是,DLL内部不时会出现问题,这意味着文件存在,但DLL不具有响应性。所以我的主要申请是挂起。
为了避免这种情况,我研究了多线程。
我的主程序有一个新类型的TMyThread,它继承了TThread,并重写了Create, Destroy, Execute。
我的主程序动态创建一个新线程(ChildThread)。儿童线程的Execute方法正在调用上面提到的LoadLibrary。
通过这样做,我可以继续我的主程序,并稍候看看ChildThread是否返回一个非零的DLLhandle。如果DLLhandle中的ChildThread在几秒钟后仍然为零,我想杀死线程,释放DLL并重试。
进一步研究,我可以看到Delphi中的线程列表。最初,在我的主程序下有4个线程。当我创建ChildTread时,会出现一个新的。几秒钟后(当调用执行和在ChildTread中调用加载库时),又会出现两个线程。我猜主DLL正在调用其他线程。
在这个阶段,我没有对ChildTread的访问,所以在Execute方法中我不能有一个while循环来查看它是否终止并退出线程。因为该线程中的实际代码已经挂起在执行中。
问:ChildTread挂起,但我的主程序仍在继续。我想从我的主程序中删除ChildThread (可能是它启动的所有其他线程),然后重试DllHandle:= LoadLibrary(DllFileName);
发布于 2020-06-12 13:09:05
我的主程序动态创建一个新线程(ChildThread)。ChildThread的执行方法是调用上面提到的LoadLibrary。
var thread := TMyThread.Create(...);在这个阶段,我没有对ChildTread的访问,所以在Execute方法中我不能有一个while循环来查看它是否终止并退出线程。因为该线程中的实际代码已经挂起在执行中。
if (thread <> nil)
and DetectWhetherThreadIsHanging(thread) // <- this is your code
then begin
TerminateThread(thread.Handle,1);
thread.Free;
end;还没测试过。连汇编都没有。但是那个方向的东西。
TerminateThread是一个危险的函数,只能在最极端的情况下使用。只有当您确切地知道目标线程正在执行什么,并且控制目标线程可能在终止时运行的所有代码时,才应该调用TerminateThread。例如,TerminateThread可能导致以下问题.
最后,再说一遍:您不只是简单地杀死线程。如果DLL在加载时被卡住,则可能有其原因,也有DLL中的错误。在99%的情况下,当一个人感到需要“杀死”一个线程或一个进程的算法原因,这是错误的方法。
编辑和可能的解决方案
但是还有其他由LoadLibrary(DLL)调用的线程。他们没有被杀。因此,我认为DLL没有被释放,所以我不能再次调用加载库(Dll)。
我能想象到的解决方案的唯一真正方法是这个,但对你来说可能不是一个可行的解决方案。这主要取决于DLL做什么,但既然你不告诉我们我们不知道。
https://stackoverflow.com/questions/62342356
复制相似问题