线程问题(100分)

  • 主题发起人 HeXiang Lee
  • 开始时间
H

HeXiang Lee

Unregistered / Unconfirmed
GUEST, unregistred user!
1.在Dll中有一过程,如何让该dll内的该过程作为线程驻留内存中?
2.在一项目中需“获取数据”“保存数据”,我想用两个线程来做。
如何将“获取数据”得到的数据交由“保存数据”去保存。有点类似在
两个进程内内存共享。
 
unit Thread;
interface
uses
Classes, SysUtils, windows;
type
MyThread = class(TThread)
private
procedure MySend;
procedure SendString;
protected
procedure Execute;
override;
end;

implementation
uses Unit1;
{ Important: Methods and properties of objects in VCL or CLX can only be used
in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure MyThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{ MyThread }
procedure MyThread.Execute;
begin
while not Terminateddo
begin
sleep(50);
Synchronize(MySend);
end;
end;

procedure MyThread.MySend;
begin
{调用动态库中的函数和过程}
end;

//------------------------
然后在主程序中定义:
var
IC_Thread: MyThread;
IC_Thread := MyThread.Create(false);//执行

end.
 
个人认为两个线程中公用一个数据单元(Unit),在其中定义一些数据结构,或是对象,
然后同步读写,比用内存映射文件好用
 
第一個問題好辦,在線程里動態加載dll,找入口,調用. 例如:
type
TDataBox= function (var GetData:TDateTime):Boolean;stdcall;
var
DllPath:pChar;
Lib:THandle;
DataBox:TDataBox;
SetDate:TDateTime;
begin
GetMem(DllPath,100);
GetSystemDirectory(DllPath,100);
SysDir:=PChar(String(DllPath)+'/DateBox');
Lib:=LoadLibrary(DllPath);
try
if Lib<>0 then
begin
DataBox:=GetProcAddress(Lib,'DateBox');
if @DataBox<>nil then
begin
SetDate:=Date;
if DataBox(SetDate) then
ShowMessage(FormatDateTime('yyyy/mm/dd',SetDate));
end else
ShowMessage(Format('不能加載%s',[DllPath]));
end;
finally
FreeLibrary(Lib);
end;

第二個問題:
在線程外定義一些公共變量.兩個線程在讀寫時採用一些同步/互斥措施.
參考一下我寫過的一個類(採用臨界區),里面定義一個數據區,對外提供了
一數據區的指針,數據區的大小,讀與寫的方法.適合多個線程訪問而互不影響.
你也可以根據要求采用互斥對像或同步對像.
TBuffer=class
private
FPointer:pointer;
FSize:Integer;
FCritical:TCriticalSection;
procedure SetSize(const Value: Integer);
protected
public
constructor Create(ASize:Integer);
destructor Destroy;
procedure Write(const Source;
Pos,Count:Integer);
procedure Read(var Dest;
Pos,Count:Integer);
property Memory: Pointer read FPointer;
property Size: Integer read FSize write SetSize;
end;

{ TBuffer }
constructor TBuffer.Create(ASize:Integer);
begin
GetMem(FPointer,FSize);
FCritical:=TCriticalSection.Create;
end;

destructor TBuffer.Destroy;
begin
FreeMem(FPointer,FSize);
FCritical.Free;
end;

procedure TBuffer.Read(var Dest;
Pos, Count: Integer);
begin
FCritical.Enter;

try
Move(Pointer(LongInt(FPointer)+Pos)^,Dest,Count);
finally
FCritical.Release;
end;
end;

procedure TBuffer.SetSize(const Value: Integer);
begin
FCritical.Enter;
try
ReallocMem(FPointer,FSize);
FSize := Value;
finally
FCritical.Release;
end;
end;

procedure TBuffer.Write(const Source;
Pos, Count: Integer);
begin
FCritical.Enter;
try
if Count>FSize then
Size:=Count;
Move(Source,Pointer(LongInt(FPointer)+Pos)^,Count);
finally
FCritical.Release;
end;
end;
 
to All:
谢谢大家。
第一个问题还没有找到办法。
第二个问题正在按大家提供的方法进行研究。
 
没有人会第一个问题了吗?
 
静态调用没有常驻内存吗?
 
没有解决问题码?
 
第一个问题有点不明白你想怎样
你想DLL里的过程在一个新的线程里执行?
如果是就简单了
还是想要想Dos中的所谓“驻留内存”,TSR?在程序退出后还在执行?
 
要求在程序退出后还在执。
 
没有想过要这种用法的
可以考虑注册为Service 不过98下不通用
或者Driver 有点难度
smokingroom:
在线程里动态加载Dll
该线程在程序退出时也退出吧?
即使该Dll驻留了内存也没有执行时间了
 
谢谢大家!
 
顶部