多线程应用中,如何调用FreeLibrary()才能保证不死机?

han012 2001-08-09 10:29:59
多线程应用中,有N个工作线程,这N个工作线程都要调用某个DLL.
我的问题是,当主线程试图调用FreeLibrary()释放这个DLL时,如何知道
没有其他工作线程的执行正处于这个DLL中.

如果有其他工作线程的执行正处于这个DLL中,而主线程调用FreeLibrary()释放这个DLL,则造成工作线程访问无效内存空间而导致死机.
...全文
939 24 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
dash 2001-08-18
  • 打赏
  • 举报
回复
学习学习
han012 2001-08-10
  • 打赏
  • 举报
回复
昨天晚上不停的翻帖子,今天早晨也只能再给本帖子加10分了,太辛苦了. 发分
horris 2001-08-09
  • 打赏
  • 举报
回复
以下是MSDN中关于LoadLibrary的描述:
During initial process startup or after a call to LoadLibrary, the system scans the list of loaded DLLs for the process. For each DLL that has not already been called with the DLL_PROCESS_ATTACH value, the system calls the DLL's entry-point function. This call is made in the context of the thread that caused the process address space to change, such as the primary thread of the process or the thread that called LoadLibrary.
所以我认为线程可以调LoadLibrary和FreeLibrary.
如果不行,我的意见是用一个全局变量,记录使用DLL的线程个数,每个线程一开始都增加之,每个线程在结束时减少之,并判断如果是0,则FreeLibrary.当然此全局变量要采取同步措施,但很简单,用InterlockedIncrement/InterlockedDecrement就行.
roland_c 2001-08-09
  • 打赏
  • 举报
回复
to cen:注意这句话
This count is incremented if the same module is loaded by a call to LoadLibrary.
cen 2001-08-09
  • 打赏
  • 举报
回复
: horris(僧推月下门) (2001-8-9 11:36:53)

msdn说的是进程,他问的是线程,这调DLL两者是不一样的
roland_c 2001-08-09
  • 打赏
  • 举报
回复
to Kevin,其实象horris说的也是一种方法,而且似乎算他的方法最好
cen 2001-08-09
  • 打赏
  • 举报
回复
主线程创建副线程时,都调用DLL_THREAD_ATACH,DLL将为该副线程初始化TLS slot.
副线程关闭时,调用DLL_THREAD_DETACH.

是这样吗?
huanGe 2001-08-09
  • 打赏
  • 举报
回复
补充:
你那么着急释放做什么。。。WINDOWS很多资源让系统自己管理吧,他们管理的效率还是很高的,现在给你的虚拟空间是4G啊。。。。
Kevin_qing 2001-08-09
  • 打赏
  • 举报
回复
嘿嘿~,你可以使用变通的方法啊,我只是给一个建议罢了
horris 2001-08-09
  • 打赏
  • 举报
回复
下面引自MSDN:
Each process maintains a reference count for each loaded library module. This reference count is incremented each time LoadLibrary is called and is decremented each time FreeLibrary is called. A DLL module loaded at process initialization due to load-time dynamic linking has a reference count of one. This count is incremented if the same module is loaded by a call to LoadLibrary.
所以你的每个线程都各自调一遍LoadLibrary和FreeLibrary即可,互不干扰
roland_c 2001-08-09
  • 打赏
  • 举报
回复
Kevin,你的做法不是不可以,而是效率太低,如果一个函数要运行很长时间,那么其他的线程都不要使用这个函数了
cen 2001-08-09
  • 打赏
  • 举报
回复
DLL加入一个同步量(信号量),主线程在释放前,用信号量通知所有正在运行该DLL的线程结束对DLL的调用,主线程等候其它线程释放DLL
Kevin_qing 2001-08-09
  • 打赏
  • 举报
回复
我还说了要做同步啊
在来
CriticalSection sec;
if(pSomeFunc)
{
sec.Lock();
pSomeFunc(...);
sec.Unlock();
}


主线程
sec.Lock();
FreeLibrary();
sec.Unlock();


azuo_lee 2001-08-09
  • 打赏
  • 举报
回复
你这根本就不是DLL的问题,纯粹就是线程同步问题——主线程释放任何资源(不单单是DLL)之前,必须保证所有的线程都已不使用此资源。具体做法数不胜数。最简单的就是huanGe(huanGe)所说的原理。但实际操作起来,如果用全局变量实现,你必须保证线程对此变量存取的互斥性,否则可能出错。可以用InterlockedIncrement和InterlockedDecrement实现。
另外,如你所说,只要某个线程使用了DLL引出的函数(哪怕只有一个),都认为该线程使用了此DLL,都要对全局的引用计数加一。
roland_c 2001-08-09
  • 打赏
  • 举报
回复
如果你使用引用计数,在发现还有线程在使用这个DLL时,根本就不应该FreeLibrary。
han012 2001-08-09
  • 打赏
  • 举报
回复
懂是懂了,现在的问题是如果线程里面正在执行 pSomeFunc(...)时(还未返回),主线程调用FreeLibrary()释放这个DLL. pSomeFunc(...)执行失败.


roland_c 2001-08-09
  • 打赏
  • 举报
回复
同意huanGe,在进程中设置一个全局变量,每个线程要引用某个中的函数时,就将这个变量加一,不再使用时将它减一,注意同步问题,保证能正确修改此变量。
Kevin_qing 2001-08-09
  • 打赏
  • 举报
回复
你访问dll里面的数据是通过指针来做的把。
在线程里面可以通过这样来访问dll里面的函数。
if(pSomeFunc)
pSomeFunc(...);

懂了~
roland_c 2001-08-09
  • 打赏
  • 举报
回复
同意楼上
han012 2001-08-09
  • 打赏
  • 举报
回复
To: Kevin_qing
我不知道该如何理解你说的 "freelibrary后把所有指针清0"

To: huanGe
我不知道该如何理解你说的 "每个线程使用DLL", DLL中有很多输出函数, 不同的工作线程可能调用DLL中不同的输出函数. 你是指:只要工作线程调用DLL中任何输出函数都认为是"线程使用DLL"?

另外,我想补充一点:主线程调用FreeLibrary()释放这个DLL时,不能要求所有工作线程都要结束,这些工作线程可能还有其他任务要完成.
加载更多回复(4)

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧