问题:我想用多线程调用DLL!
请耐心看完,谢谢僵哥!
分不够明天再加!//类定义单元ObjCust.pas
Type
TCust=class
end;//定义一个客户类//DLL部分,我的类在DLL内部处理,不导出!
uses
ObjCust;
procedure DLLInterfaceFunction;
var
objCust:TCust;
begin
objCust:=TCust.Create;
//业务处理
objCust.Save()//持久化数据,调用数据访问层
end;//主调进程(上述dll是我的一个业务处理插件,这个DLL插件我是用COM+调用的,我想在COM+中做一个线程池,当客户申请一个操作,加入申请作业队列,并调用DLL),应用2个以上线程来调用DLL
procedure RequestDLL;
begin
LoadLibrary('')
GetprocAddress('DLLInterfaceFunction')
FreeLibrary;end;procedure TThread1.Execute()
begin
//问题=====在这里用不用线程同步来避免线程串扰========
//这样创建的对像是不是被创建到全局区还是在各自线程的堆栈中?如果这样和单线程没什么区别
//我的理想处理方法是这样的:
//线程可并行、独立调用我的DLL插件,不用线程同步,说白了就是让对象创建在线程堆栈中,而不是在全局区,这样并发性就提高了!
//临界区保护开始
RequestDLL
//临界区保护
end;
请耐心看完,谢谢僵哥!
分不够明天再加!//类定义单元ObjCust.pas
Type
TCust=class
end;//定义一个客户类//DLL部分,我的类在DLL内部处理,不导出!
uses
ObjCust;
procedure DLLInterfaceFunction;
var
objCust:TCust;
begin
objCust:=TCust.Create;
//业务处理
objCust.Save()//持久化数据,调用数据访问层
end;//主调进程(上述dll是我的一个业务处理插件,这个DLL插件我是用COM+调用的,我想在COM+中做一个线程池,当客户申请一个操作,加入申请作业队列,并调用DLL),应用2个以上线程来调用DLL
procedure RequestDLL;
begin
LoadLibrary('')
GetprocAddress('DLLInterfaceFunction')
FreeLibrary;end;procedure TThread1.Execute()
begin
//问题=====在这里用不用线程同步来避免线程串扰========
//这样创建的对像是不是被创建到全局区还是在各自线程的堆栈中?如果这样和单线程没什么区别
//我的理想处理方法是这样的:
//线程可并行、独立调用我的DLL插件,不用线程同步,说白了就是让对象创建在线程堆栈中,而不是在全局区,这样并发性就提高了!
//临界区保护开始
RequestDLL
//临界区保护
end;
结论如下:
1.在线程函数 内定义的变量 被分配在 本(自己)线程堆栈空间内,所以不用进行 线程同步处理
2.在线程函数 内使用全局变量 需要进行线程同步处理
3.在线程函数 内使用的全局变量,是线程变量,也可以不用进行线程同步处理
譬如:delphi可以用Threadvar 关键字定义
vc中可以使用__declspec(thread)根据以上测试结果,LZ的问题:
这样创建的对像是不是被创建到全局区还是在各自线程的堆栈中?
》》应该创建在 各自线程的堆栈中 (创建的对象中必须没有对全局变量的引用)以上,个人观点,如有不妥,还请各位指正!谢谢!
线程堆栈是用于维护线程在执行代码时需要的所有函数的参数与局部变量!
很显然,LZ的TCust.Create是创建在堆中,也就是进程的一块区域中,在线程的私有栈中保存了Cust的引用!这时创建的TCust的数据区已被加上使用标识,当下次别的线程再进行LoadLibrary并TCust.Create时,显然是分配不到刚刚的数据空间的。
这时当时间片分配到任何一个工作线程后,它们均可以1.先从自己堆栈中恢复对象引用2.继续数据操作!