偶在DLL里面用线程的时候出的问题,有人能帮忙解决吗,下面是主要的代码.//这个是线程unit CheckThread;interfaceuses
Classes {$IFDEF MSWINDOWS} , Windows {$ENDIF};type
MyThread = class(TThread)
public
constructor Create(ClassNum:integer);
private
ClassNum:integer;
LastRes:integer;
Ready:boolean;
procedure Init;
protected
procedure Execute; override;
end;implementationprocedure MyThread.Execute;
begin
while not(Terminated) do
begin
Suspend; Ready:=true;
end;
inherited;
end;constructor MyThread.Create(ClassNum:integer);
begin
inherited Create(false);
self.ClassNum:=ClassNum;
Init;
end;procedure MyThread.Init;
begin
LastRes:=0;
Ready:=false;
end;end.由于种种原因,DLL里面是这样用线程的
//DLL的部分代码,实际执行的部分。
library xxx;var
Thread:MyThread;
SaveDllProc:TDLLProc;......
......procedure LibExit(Reason: DWord);
begin
if Reason = DLL_PROCESS_DETACH then
begin
if Thread <> nil then
begin
Thread.Terminate;
if Thread.Suspended then Thread.Resume;
Freeandnil(Thread);
end;
end;
// SaveDllProc(Reason); // call saved entry point procedure
end;exports
..............begin
Thread := MyThread.Create(4);
SaveDllProc := DllProc;
DllProc := @LibExit; // install LibExit exit procedure
LibExit(DLL_PROCESS_ATTACH);
Randomize;
end.希望是 程序在DLL载入时加载线程但不启动Execute。(正常)
DLL卸载时关闭线程(可能是运行的也可能是Suspened)。(程序挂起)问题有2个
1、如果加上SaveDllProc(Reason),就是去掉的那行,则系统将在运行到该行时报错。
2、如果加载Dll,然后卸载掉,会停在Freeandnil(Thread);线程没有Exit,
如果在Freeandnil(Thread)前面加上Thread.WaitFor;那么,就会停在Waitfor处,第一个问题不是很重要。
第2个问题很关键,我在调试的时候有时可以正常Exit线程,但大多数时候就不能。
我一直希望了解如果是在挂起(Suspended)的状态下,使线程正常关闭的正确手法是什么。本人使用的环境是 Delphi 2005 (9.0.1761.24408), 使用 Delphi For Win32 , WindowsXP SP2.
Classes {$IFDEF MSWINDOWS} , Windows {$ENDIF};type
MyThread = class(TThread)
public
constructor Create(ClassNum:integer);
private
ClassNum:integer;
LastRes:integer;
Ready:boolean;
procedure Init;
protected
procedure Execute; override;
end;implementationprocedure MyThread.Execute;
begin
while not(Terminated) do
begin
Suspend; Ready:=true;
end;
inherited;
end;constructor MyThread.Create(ClassNum:integer);
begin
inherited Create(false);
self.ClassNum:=ClassNum;
Init;
end;procedure MyThread.Init;
begin
LastRes:=0;
Ready:=false;
end;end.由于种种原因,DLL里面是这样用线程的
//DLL的部分代码,实际执行的部分。
library xxx;var
Thread:MyThread;
SaveDllProc:TDLLProc;......
......procedure LibExit(Reason: DWord);
begin
if Reason = DLL_PROCESS_DETACH then
begin
if Thread <> nil then
begin
Thread.Terminate;
if Thread.Suspended then Thread.Resume;
Freeandnil(Thread);
end;
end;
// SaveDllProc(Reason); // call saved entry point procedure
end;exports
..............begin
Thread := MyThread.Create(4);
SaveDllProc := DllProc;
DllProc := @LibExit; // install LibExit exit procedure
LibExit(DLL_PROCESS_ATTACH);
Randomize;
end.希望是 程序在DLL载入时加载线程但不启动Execute。(正常)
DLL卸载时关闭线程(可能是运行的也可能是Suspened)。(程序挂起)问题有2个
1、如果加上SaveDllProc(Reason),就是去掉的那行,则系统将在运行到该行时报错。
2、如果加载Dll,然后卸载掉,会停在Freeandnil(Thread);线程没有Exit,
如果在Freeandnil(Thread)前面加上Thread.WaitFor;那么,就会停在Waitfor处,第一个问题不是很重要。
第2个问题很关键,我在调试的时候有时可以正常Exit线程,但大多数时候就不能。
我一直希望了解如果是在挂起(Suspended)的状态下,使线程正常关闭的正确手法是什么。本人使用的环境是 Delphi 2005 (9.0.1761.24408), 使用 Delphi For Win32 , WindowsXP SP2.
解决方案 »
- 如何获得窗口的句柄?
- 在dbgrid中,如何用不同的颜色显示字段信息?
- 把一个应用程序做成什么才能让别的语言调走呢?做成ACTIVEX可以吗?做成自动化服务器可以吗?
- ***讀取VFP建的庫dbf數據庫问题**急急急
- datetimepicker操作问题 请教
- 一个傻问题,为什么我调用最简单的dll的函数老是报pointer opretion error?
- 这个代码如何改?--------------关于取得文件夹下的文件清单?
- 关于webservice客户端问题
- 有谁知道Wwindows优化大师的标题栏上有了什么探件啊,我好想知道!!!!!!!!!!
- 如何让其他程序不最小化
- 数据导入到Excel里头,由于数据太长出现MEMO,该怎么办?
- devorgchart如何连接SQL SERVER?
我现在取消掉Freeandnil(Thread)以后DLL退出时会自动Exit线程。(按道理Delphi的内存管理会处理掉这个Thread对象,但个人无法保证这个过程)
不过不知道这么做会不会有什么问题。如果确实问题是如我上面说言,那么就可以理解为什么加了WaitFor或者Free(Destory里面含WaitFor)会等待了,因为WaitFor必须等待线程结束的返回事件,于是结束进程的响应过程和正在等待的函数体相冲突,于是就产生了死锁。个人验证,正确的Free的过程确实如上面所述。
下面是验证代码,有兴趣的自己调试一下
//Unit1.pas
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, CheckThread;type
TForm1 = class(TForm)
procedure FormDblClick(Sender: TObject);
private
{ Private declarations }
public
Test:MyThread;
i:boolean;
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormDblClick(Sender: TObject);
begin
i:=not i;
case i of
true: Test :=MyThread.Create(3,false);
false: begin
Test.Terminate;
Test.Resume;
Test.WaitFor;
Test.Free;
end;
end;
end;end.
如果必须Free,最好怎么做?