不要在dll及ocx的CXXXApp::InitInstance中调用创建线程及关闭线程的操作
来源:互联网 发布:剑灵灵男方脸捏脸数据 编辑:程序博客网 时间:2024/06/05 10:53
问题:
写了个ocx控件,然后在ocx控件注册时注册成功了,但regsvr32还在进程管理器中。
分析后发现在注册ocx控件时,ocx控件的代码CXXXApp::InitInstance会被调用,注册完后CXXXApp::ExitInstance会被调用。
由于在ExitInstance中调用退出线程,并等待线程退出的代码,死锁了,所以regsvr32卡死在进程管理器了。
条件1:
Let me get this out of the way up front: Creating a thread from DllMain
is not recommended. The discussion here has to do with explaining the behavior you may observe if you violate this advice.
Commenter Pete points out that "according to Usenet" creating a thread in DllMain
is supposed to deadlock, but that's not what he saw. All he saw was that the thread entry procedure was not called.
I'm going to set aside what "according to Usenet" means.
Recall how a thread starts up. When you call CreateThread
, a kernel thread object is created and scheduled. Once the thread gets a chance to run, the kernel calls all the DllMain
functions with the DLL_THREAD_ATTACH
code. Once that's done, the thread's entry point is called.
The issue with deadlocks is that all DllMain
functions are serialized. At most one DllMain
can be running at a time. Suppose a DllMain
function is running and it creates a thread. As we noted above, a kernel thread object is created and scheduled, and the first thing the thread does is notify all the DLLs with DLL_THREAD_ATTACH
. Since DllMain
functions are serialized, the attempt to send out the DLL_THREAD_ATTACH
notifications must wait until the current DllMain
function returns.
That's why you observe that the new thread's entry point doesn't get called until after you return from DllMain
. The new thread hasn't even made it that far; it's still working on the DLL_THREAD_ATTACH
notifications. On the other hand, there is no actual deadlock here. The new thread will get itself off the ground once everybody else has finished doing their DllMain
work.
So what is this deadlock that Usenet talks about? If you've been following along, you should spot it easily enough.
If your DllMain
function creates a thread and then waits for the thread to do something (e.g., waits for the thread to signal an event that says that it has finished initializing, then you've created a deadlock. The DLL_PROCESS_ATTACH
notification handler inside DllMain
is waiting for the new thread to run, but the new thread can't run until the DllMain
function returns so that it can send a new DLL_THREAD_ATTACH
notification.
This deadlock is much more commonly seen in DLL_PROCESS_DETACH
, where a DLL wants to shut down its worker threads and wait for them to clean up before it unloads itself.You can't wait for a thread inside DLL_PROCESS_DETACH
because that thread needs to send out theDLL_THREAD_DETACH
notifications before it exits, which it can't do until your DLL_PROCESS_DETACH
handler returns.
(It is for this thread cleanup case that the function FreeLibraryAndExitThread
was created.)
条件2:
所以:
尽量不要在dll及ocx的InitInstance中创建线程;
不允许在ExitInstance 中关闭线程并等待线程结束;
- 不要在dll及ocx的CXXXApp::InitInstance中调用创建线程及关闭线程的操作
- 关于MFC DLL CWinApp::InitInstance()中创建线程的问题 易造成死锁
- windows中线程及dll函数调用
- VC中DLL的创建及调用
- 在Java中,关于线程的创建,方法及生命周期
- Android中线程的创建及启动
- 进程、线程、线程的创建及多线程
- 多线程,线程创建及关闭句柄存在的问题,终止线程的运行的几个函数
- 在DLL 的DllMain函数中创建线程
- 线程的创建及运行
- 工作线程中调用UI线程创建的窗口的UpdateData会导致Assert的问题及解决办法.
- 工作线程中调用UI线程创建的窗口的UpdateData会导致Assert的问题及解决办法
- 工作线程中调用UI线程创建的窗口的UpdateData会导致Assert的问题及解决办法(ZZ)
- DLL文件在Delphi的创建及调用
- 第四十一讲 深入线程(操作线程的,执行,挂起,恢复,关闭 及 Join的用法)
- JVM关闭及线程的退出
- 线程的正确处理及关闭示例
- VC中DLL的创建及调用方法
- 搭建cassandra单数据中心集群(笔记)
- Android高级应用开发(基础篇) - stage9 - 学习笔记
- Android fragment相关
- linux下增加虚拟内存
- linux安装mysql提示conflicts with file from package的解决办法
- 不要在dll及ocx的CXXXApp::InitInstance中调用创建线程及关闭线程的操作
- zookeeper basic 2
- 怎样在centos上手动安装配置lnmp环境
- C#中Hashtable的遍历办法
- oracle提交了之后怎么回滚
- Vlookup函数对不一致数据的比对
- Apache Karaf用户指导
- Jdbi in范围查询
- c# 计算2个时间的时间差