- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
DllMain和多线程死锁 guke1978 1
DllMain和多线程死锁 guke1978 1
用户操作[留言][发消息][加为好友]guke1978_123的文章原创1篇翻译0篇转载0篇评论5篇订阅我的博客存档
2006年03月(1)DllMain和多线程死锁
关于本文
本文是我在查一个ATL singleton中的线程为何不能完全退出的bug时,查阅多本相关书籍,做了多个测试程序得出的结果。如有不正确的地方,欢迎指正。
正文
在Windows操作系统中,DLL(动态链接库)技术有很多优点。例如,多个应用程序可以共享一个DLL文件,真正实现了资源共享,大大缩小了应用程序的执行代码,有效地利用了内存,而且DLL文件作为一个单独的程序模块,封装性、独立性好,有利于提高软件开发和维护的效率。
DllMain入口指针,当进程和线程启动和终止时被系统调用,分别进行创建资源和释放资源等操作,特别地,也可以在DLL响应DLL_PROCESS_ATTACHDLL响应DLL_PROCESS_DETACHDllMain中无论是创建DllMain的顺序调用规则。
Windows操作系统中是顺序调用DLL的入口函数DllMain的。当进程被创建时,系统也为该进程创建了一个互斥对象。每个进程都有它自己的互斥对象。进程互斥对象的一个作用是,序列化在需要调用DllMain的种情况下DllMain的执行:DLL_PROCESS_ATTACH、DLL_THREAD_ATTACH、DLL_THREAD_DETACH和DLL_PROCESS_DETACHDLL。DllMain函数的第二个参数指示出调用DllMain的原因。
中创建DllMain的这个顺序调用规则,程序就会发生死锁。下面就DllMain中创建
考虑在一个多线程程序中,某个DLL被加载进程地址空间时,该DLL的DllMain启动了一个线程,然后立即调用一个应答事件对象的WaitForSingleObject函数,以确认在继续进行其余的DllMain处理之前,新产生的线程能够正确地执行一些操作。类似的代码如下:
HANDLEthread_handle=NULL该DLL内部线程的句柄
DWORDthread_id该DLL内部线程的
应答事件的句柄
DWORD WINAPI InSideDll_ThreadProc(LPVOID p
的操作完成后,
BOOL APIENTRY DllMain(HANDLE hModule DWORD ul_reason_for_call,LPVOID lpReserved switch(ul_reason_for_call
正在映射到进程地址空间中
DisableThreadLibraryCalls((
//创建DLL内线程使用的事件对象
g_hEvent=:CreateEvent(NULL,FALSE,FALSE,_T(hello11
//创建DLL内线程对象
g_thread_handle=:CreateThread(NULL InSideDll_ThreadProc,(LPVOIDthread_id
//等待刚创建的线程完成相关操作
:WaitForSingleObject(g_hEvent,INFINITE
//清除资源
:CloseHandle(g_ g_ g_thread_handle=NULL
:CloseHandle(g_hEvent g_hEvent=NULL
正在从进程地址空间中卸载
如果对这样的程序进行调试,通过Call Stack窗口可以看到该程序正在等待DllMain内部的线程处理,而Output窗口中也没有打印出--operations.--语句。可见线程函数InSideDll_ThreadProc根本就没有得到运行的机会。
结合DllMain的顺序调用规则,答案就很简单了。在程序运行过程中,第一个线程对LoadLibrary的调用引起操作系统获取进程互斥对象并以DLL_PROCESS_ATTACH值调用该DLL的DllMain。该DLL的DllMain函数产生第二个线程。无论何时当进程产生一个新线程时,操作系统将获取进程互斥对象,以便于它可以为DLL_THREAD_ATTACH值调用每个加载的DLL的DllMain函数。在这个特定的程序中,第二个线程阻塞,因为第一个线程还保持着进程互斥对象。不幸的是,第一个线程然后调用WaitForSingleObject确认第二个线程能够正确地完成一些操作。因为第二个线程被阻塞在进程互斥对象上,这个进程互斥对象还被第一个线程所持有,而第一个线程要等待第二个线程从而也被阻塞,结果就导致了死锁。如下图所示。
另外,DisableThreadLibraryCalls函数并不能解除这种死锁,相关原因在《Windows核心编程》一书中有更详尽的描述,这里就不再
您可能关注的文档
最近下载
- 学堂在线 海上求生与救生 章节测试答案.docx VIP
- 2025年甘肃省兰州建投物业管理有限公司招聘笔试备考题库及答案解析.docx VIP
- 学堂在线 生活英语读写 期末考试复习题答案.docx VIP
- 医用护理垫技术要求.docx VIP
- 裂项相消求和法-【名师经典教学设计课件】.doc VIP
- 走进现代舞知到智慧树期末考试答案题库2025年浙江大学.docx
- 声导抗与声反射测试及应用.pptx VIP
- 《急诊外科急救技术》课件.ppt VIP
- 2024年深圳学业水平考试信息技术A卷测试题及答案.docx VIP
- 2025年甘肃省兰州建投物业管理有限公司招聘笔试模拟试题及答案解析.docx VIP
原创力文档


文档评论(0)