DLL全局变量与DLL内线程,谁的生存周期长? 我觉得应该是DLL全局变量的长,但最近做的东西又好象不是这么回事,想请教下。主要是怕DLL线程生存周期更长的话,会去操作已经死亡的DLL全局变量,引发错误。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 线程你在DLL卸载时要结束,这样全局变量应该比线程长. 主要不了解DLL卸载时的善后顺序 线程是属于进程的,即使是在DLL内创建的,也可能在DLL卸载后还存在的。DLL就是一砣代码而已,作为一个模块,会在卸载时被强制一起清除的,只有它的全局变量和资源。 我做了个最简单模型,DLL里会启动的线程如:void threadInDll(PVOID pv){ while(TRUE) { Sleep(1000); }}动态加载DLL,启动该线程,卸载DLL,因为TRUE随DLL消亡,线程仍存在,报错。由此证明了DLL全局变量的生存周期跟DLL一样,但DLL创建的线程,生存期不随DLL卸载而消亡。 全局变量析构是在DLL_PROCESS_DETACH的时候,因而比线程的生存期长 你这个概念有点不对,TRUE是一个宏,是1,一个立即数,存在于代码中,不是全局变量。你报错是因为你的DLL被卸载后,这个函数的代码所处的地址空间也随之一起释放了,会产生非法访问错误。你在你主模块里面定义线程函数,然后传进DLL让DLL中的代码创建线程执行这个函数,在DLL卸载时就不会挂了。 如果是:全局变量BOOL x = TRUE;void threadInDll(PVOID pv){ while(x) { Sleep(1000); }}呢(先不讨论怎么改变,那样会展开新话题),这个应该符合主题吧,结果应该是报错,表明DLL创建的线程比DLL的全局变量生存周期长吧。 结果肯定报错的,DLL中的全局变量随DLL卸载销毁,地址空间被释放。如果threadInDll函数也是在DLL中的话,那就访问x的时候挂的,也可能访问指令时挂的。DLL创建的线程和主程序创建的线程没有任何区别,严格说拿线程和全局变量不能拿来作比较。 如果全局变量属于主程序 什么dllmain的?因该是全局变量堆栈先释放 主程序结束 线程因该是异常结束吧 因为线程的代码在dll的内存上。所以,在dll卸载前,线程必须被终止。如果卸载dll而线程仍然运行的话则必出错,因为线程所在的内存已经无效,cpu再取指必出错。全局变量在dll内存中,所以生存周期与dll一样长。所以时间顺序如下:(1) 线程终止(2) dll卸载,全局变量无效。全局变量生存周期》线程。但如果你new 一段内存,然后把线程代码copy到这段内存中,再开始线程的话,那就例外。 根本不是生存周期的问题...而是DLL退出时, DLL创建的一切资源必须先释放的, 引用DLL内部的任何资源也必须先释放的. 全局变量肯定是在DllMain运行完之后才会释放掉的 是指12楼说的new出来的代码吗,new是在系统堆栈上的吧,进程结束不影响里面的代码吧。 这里new用的堆是进程的用户地址空间中,进程结束时都会没的没有系统堆栈这个说法 哦,搞错了,还是进程用户空间内,内存泄露在进程结束后不存在了。现在又回到了怎么实现这个new内存然后copy线程代码进去然后启动线程的技术上来了。 new用的堆不是可执行的,如果有数据执行保护则不行你可以使用HeapCreate创建一个可执行的堆,然后用HeapAlloc在上面分配一块内存,然后把代码放在上面 楼上的,你们在讨论什么啊?难道在DLL中创建的线程,在DLL卸载时,不需要先将线程退出吗?为什么还会有谁的生命期更长这种讨论。 楼上的,你的概念就错了,线程在哪儿创建的根本没有影响,有影响的是线程所运行的代码、要访问的地址还存不存在,如果在DLL地址空间中被卸载了、不存在了,就会产生非法访问异常,程序挂掉。 主要看的书有限,没有能够看到DLL卸载前必须要把DLL创建的线程结束的编程原则,所以就有了题目所问。不过话说回来,不管有没有什么“标准编程原则”,实际应用中应该难免由DLL创建线程,如果线程时间难控制,那么卸载DLL前就只能强退线程了吗?也就是对DLL创建的线程在卸载DLL前如何善后的问题,请指教。 我有一个api hook的用到了这个,把你的邮箱发来我给你 DLLMAIN 里面有几个入口 CASE标志 加载\卸载 等最好结合起来 MFC中函数怎么调用,帮我看一下代码,谢谢啦 哥也.我想问一个关于单文档.多视图的问题.为啥要换一下GWL_ID? 新手请教:在对话框上的编辑框(Edit)如何知道用户按下的是什么键? 关于数据库的刷新,急! 如何在CListView中自画后改变线的颜色? 哪里有好的外国vc资源网站 请问统计汉字和英文字符及标点符号的算法应怎样写? 请教几个vc函数的功能 有做过短信平台系统的朋友请进来指点下 C++ udp 语音传输 使用 wavein waveout 的断续问题 CListCtrl 滚动条 MFC的CMSComm的Create方法
void threadInDll(PVOID pv)
{
while(TRUE)
{
Sleep(1000);
}
}动态加载DLL,启动该线程,卸载DLL,因为TRUE随DLL消亡,线程仍存在,报错。由此证明了DLL全局变量的生存周期跟DLL一样,但DLL创建的线程,生存期不随DLL卸载而消亡。
你这个概念有点不对,TRUE是一个宏,是1,一个立即数,存在于代码中,不是全局变量。
你报错是因为你的DLL被卸载后,这个函数的代码所处的地址空间也随之一起释放了,会产生非法访问错误。
你在你主模块里面定义线程函数,然后传进DLL让DLL中的代码创建线程执行这个函数,在DLL卸载时就不会挂了。
全局变量BOOL x = TRUE;
void threadInDll(PVOID pv)
{
while(x)
{
Sleep(1000);
}
}
呢(先不讨论怎么改变,那样会展开新话题),这个应该符合主题吧,结果应该是报错,表明DLL创建的线程比DLL的全局变量生存周期长吧。
DLL创建的线程和主程序创建的线程没有任何区别,严格说拿线程和全局变量不能拿来作比较。
所以,在dll卸载前,线程必须被终止。如果卸载dll而线程仍然运行的话则必出错,因为线程所在的内存已经无效,cpu再取指必出错。
全局变量在dll内存中,所以生存周期与dll一样长。所以时间顺序如下:
(1) 线程终止
(2) dll卸载,全局变量无效。
全局变量生存周期》线程。但如果你new 一段内存,然后把线程代码copy到这段内存中,再开始线程的话,那就例外。
而是DLL退出时, DLL创建的一切资源必须先释放的, 引用DLL内部的任何资源也必须先释放的.
全局变量肯定是在DllMain运行完之后才会释放掉的
没有系统堆栈这个说法
你可以使用HeapCreate创建一个可执行的堆,然后用HeapAlloc在上面分配一块内存,然后把代码放在上面