CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  进程/线程/DLL

问有关于dll和线程问题,解决就给分,没有答案宁肯扣信誉分也不结贴

楼主qianyong325(帝王企鹅)2005-06-21 12:09:31 在 VC/MFC / 进程/线程/DLL 提问

我在dll里创建了一个线程,查资料知道不能在InitInstance()中创建,这个我弄好了,那么在主程序结束的时候,我怎么退出线程呢?比如说主程序点击右上的关闭按钮,我尝试在dll的ExitInstance()函数里设置一个Event,然后在线程中WaitForSingleObject(),然后在ExitInstance()中waitForSingleObject(myhThread,INFINITE)   ,但是到waitForSingleObject(myhThread,INFINITE)程序始终在等待,估计是线程没有退出!!!相同的代码如果不用在dll中直接在一个exe中,是没有问题的!!!!这个问题困扰我好几天了,请各位高手指教,解决了马上给分,如果分不够另外开贴送分!! 问题点数:100、回复次数:22Top

1 楼aben456(金珠MERP)回复于 2005-06-21 12:25:18 得分 0

extern   "C"   int   APIENTRY   DllMain(HINSTANCE   hInstance,   DWORD   dwReason,   LPVOID   lpReserved)  
  {  
  UNREFERENCED_PARAMETER(lpReserved);  
  if   (dwReason   ==   DLL_PROCESS_ATTACH)  
  {  
  //dll   attach,初始化  
  }  
  else   if   (dwReason   ==   DLL_PROCESS_DETACH)  
  {  
                        //ll   detach  
                        //可以试试让线程在这里退出  
                      }  
  return   1;  
  }  
  Top

2 楼younggle(洋溢)回复于 2005-06-21 12:37:40 得分 0

你的线程是怎么结束的?  
   
  线程函数  
  while(m_bThreadRun)  
  {  
      ....  
  }  
   
  结束的方法:  
  m_bThreadRun   =   FALSE;  
  waitForSingleObject(myhThread,INFINITE);  
   
  但是线程一定要保证是一直在循环,能检测到   m_bThreadRun   =   FALSE  
   
   
  Top

3 楼goodboyws(深夜不眠者(VCMVP))回复于 2005-06-21 12:53:11 得分 0

你的线程函数足够简单么,换成空循环试试,也许在别的地方阻塞。Top

4 楼qianyong325(帝王企鹅)回复于 2005-06-21 13:47:27 得分 0

to:younggle(洋溢),是一直在循环,能检测到m_bThreadRun,我调试了一下,是在线程return   0的时候,跟进去是AfxEndThread()函数不动了,在往里是汇编,我看不懂,是__ExitThread()这里死锁不往下走了,不知到那位高人能来解说一下?  
   
   
  to:aben456(相逢一笑)     我用向导生成的dll,已经看不到dllmain了,不过InitInstance和ExitInstance实际上调用的还是dllmain,问题依然Top

5 楼qianyong325(帝王企鹅)回复于 2005-06-21 14:08:36 得分 0

没有人能回答了吗?我又测了一下,如果在线程中  
  while(bRun){  
  .....  
  return   0;  
  }  
  是可以退出的,如果是  
  while(bRun){  
   
  }  
  return   0;//   在这里放断点是可以到的,但是在往下跑就死锁了!  
   
  就不行了,所以怀疑是我设置bRun=FALSE的位置不对,我是在dll的ExitInstance里设置的,因为我只又在这里才知道主程序要退出啊!!!  
  Top

6 楼linur(林子大了,什么鸟都有)回复于 2005-06-21 14:16:13 得分 100

看来你创建的是MFC形式的DLL,那么你可以就在ExitInstance里结束你创建的线程  
  怎么结束,得取决于你的线程函数的写法  
  1.如果你的线程函数是没有循环,但是用了等待变量,那么你应该调用SetEvent唤醒它,  
  让线程自行结束就行  
  2.如果你的线程函数是有while(bContinue)这样的循环,你又在ExitInstance里  
  加入waitForSingleObject(myhThread,INFINITE)发现始终在等待,  
  这是因为你bContinue还是为true,或者你在线程函数中也有waitForSingleObject(h1)  
  这样的函数导致你的线程还在执行,那么你在ExitInstance里  
  直接设置它   bContinue=false   ,若有等待变量的话,你还应该SetEvent(h1)  
  这样线程就自行结束了  
  Top

7 楼qianyong325(帝王企鹅)回复于 2005-06-21 14:42:44 得分 0

to:linur(林曦)  
  我的线程是这样的  
   
  UINT   MyFunc(   LPVOID   pParam   )  
  {  
        while(bRun)   //   bRun是全局变量  
          {  
                if(::WaitForSingleObject(pParma->m_hEvent,10)   ==   WAIT_OBJECT_0)  
                    {  
                          ......           //   我自己的操作  
                    }  
          }  
          return   0;           //   当在ExitInstance里设置bRun   =   false,函数在这里停住了,跟进去是  
                                      //   AfxEndthread()   死锁了,实在是不明白问题原因  
  }  
   
  //   下面是ExitInstance的代码  
  int   CAlmMessApp::ExitInstance()  
  {  
        bRun   =   FALSE;  
        ::WaitForSingleObject(p->m_hThread,INFINITE)   //   p   =   AfxBeginThread(DelayFunc,this);  
  }  
   
  现在的问题是如果退出的代码不在ExitInstance里,是没有问题的,如果是上面的样子,怎在Top

8 楼happytan(强就一个字)回复于 2005-06-21 14:58:44 得分 0

HANDLE   *m_ExitThread;全局变量  
   
  #define   MaxWaitTimes   100     //线程每运转一次的间隔  
   
   
  *****线程******  
  for(;;)  
  {  
      DWORD   dwRet=::WaitForSingleObject(m_ExitThread,   MaxWaitTimes);  
      if   (dwRet!=WAIT_OBJECT_0)    
      {  
          这里,你想干嘛就干嘛!  
      }  
      else  
      {  
          CloseHandle(m_ExitThread);  
          return   0;  
      }  
  }  
   
  *******结束线程*********  
  Close()  
  {  
      if(m_ExitThread!=NULL)  
            VERIFY(SetEvent(m_ExitThread));//设置线程退出  
   
      Sleep(MaxWaitTimes);//等待一个线程运转周期,确保线程退出  
  }Top

9 楼aben456(金珠MERP)回复于 2005-06-21 17:17:33 得分 0

bRun   =   FALSE;  
  bRun是在哪里定义?  
  又是在哪里修改的?  
  修改成功了没有?Top

10 楼qianyong325(帝王企鹅)回复于 2005-06-22 14:36:15 得分 0

问题解决了,还是我自己解决的,郁闷~  
  我发现不能在dll的exitInstance函数里waitforsingleobject(p->m_hThread),这样会死锁,  
  其中,   CWinthread   *p   =   AfxBeginThead(Mythread,this);但是这样的用法在exe程序中是可以的,我现在折中的解决办法是另外设置一个Handle   hquit,在thread退出时设置这个SetEvent(hquit),然后在  
  dll里的ExitInstance(){   ::WaitForSingleObject(hquit,INFINITE);}  
   
  虽然问题解决了,但是原理没弄懂,希望有懂得高手来给解释一下,为什么一样的代码在dll里会死锁,在exe程序里就可以用!!!  
   
   
  btw:感觉在csdn里想问个答案真tmd难,在c++板块好点,你们说那么多星星都是怎么升上去的?  
   
  Top

11 楼linur(林子大了,什么鸟都有)回复于 2005-06-22 18:01:20 得分 0

to   qianyong325(帝王企鹅)  
  你应该在主程序(就是应用程序对象类)的函数ExitInstance里(而不是DLL类那个ExitInstance)  
  写上    
    bRun   =   FALSE;    
    ::WaitForSingleObject(hThread,INFINITE);    
  不用Wait函数也可以,你可以换为sleep(100);防止主线程退得太快而让辅助线程来不及正常退出    
   
  你原来的写法就会出来你说的问题,这是因为你虽然是创建在DLL中定义的线程,但是创建的线程  
  还是在主程序空间,这样你退出时,主程序会强行销毁所有的资源,因此你不应该让DLL的ExitInstance去控件线程的退出Top

12 楼qianyong325(帝王企鹅)回复于 2005-06-23 09:33:28 得分 0

那为什么我改了退出方式以后,在dll的exitInstance里就可以退出了,实际上我不能修改exe里的代码,我只知道主程序在退出的时候会调用一次FreeLibrary,FreeLibrary的时候应该会调用dll里exitInstance(),这个函数,这个时候应该还没有销毁资源吧?如果都销毁了,那我更改退出方式应该也不能解决问题!!!  
   
  欢迎继续讨论Top

13 楼linur(林子大了,什么鸟都有)回复于 2005-06-23 12:51:08 得分 0

你用另外设置一个Handle   hquit,在thread退出时设置这个SetEvent(hquit),就和我上面说的  
  在主线程里设置bRun   =   FALSE是一样的道理,你的方法也是让主线程去设置某个控制变量让线程退出.  
  而不是把控制代码放到线程的ExitInstance()Top

14 楼tigerfox(风之力:=Doing.浪淘沙)回复于 2005-06-23 13:10:56 得分 0

结束线程:  
   
  TerminateThread(hNetHandle[i],0);  
  CloseHandle(hNetHandle[i]);Top

15 楼qianyong325(帝王企鹅)回复于 2005-06-23 16:21:25 得分 0

to:   linur(林曦),你似乎没有明白我的解决办法。实际不是你说的而是  
  UINT   MyThread(void   *   pParam)  
  {  
        while(bRun)  
          {  
                ...  
          }  
       
      ::SetEvent(hquit);  
      return   0;  
  }  
   
  dllApp::ExitInstance()  
  {  
      bRun   =   false;  
      ::WaitForSingleObject(hquit,INFINITE);  
       
      ...  
  }  
   
  to:tigerfox(风之力:=Doing.浪淘沙)  
  我知道用TerminateThread()也可以结束线程,而且结束之后还应该delete   thread;否则有泄漏,但是这种方法是mircosoft极力反对的,几乎所有的windows编程经典著作都说应该让线程自己结束,连afxEndThread这个函数都不推荐使用,作为一个星星,你就这样教导新人吗?  
  Top

16 楼umbrella1984(雨伞(KEN))回复于 2005-06-26 02:10:29 得分 0

看不出是哪里出问题了~有点诡异,楼主是否中间有调用过CloseHandle?Top

17 楼linur(林子大了,什么鸟都有)回复于 2005-06-26 17:01:28 得分 0

to:   qianyong325(帝王企鹅)    
  你把bRun   =   false;   放到dllApp::ExitInstance()里,注意仍然是主线程在执行这个函数。我已经在VC2003下写了测试过了,你这样做的结果虽然没有导致死锁,但是导致了主线程饿死现象,看看你写的代码  
  dllApp::ExitInstance()  
  {  
      bRun   =   false;  
      ::WaitForSingleObject(hquit,INFINITE);  
       
      ...  
  }  
  当主线程执行到bRun=false;之前就释放掉了,其原因是当程序退出时,主线程会先执行ExitProcess释放掉你的辅助线程,从而让你的MyThread线程非正常退出,也就是直接从while循环中退出,从而MyThread不能正常执行::SetEvent(hquit);这句代码再次唤醒主线程,导致让主线程永久睡眠了(饿死了)  
  不知道这样的解答你是否满意:)Top

18 楼xqk(夏乾坤)回复于 2005-06-26 17:02:59 得分 0

markTop

19 楼qianyong325(帝王企鹅)回复于 2005-06-27 11:14:14 得分 0

to:linur(林曦)  
  在主程序的exitInstance里调用了::FreeLibrary(),应该是在::FreeLibrary()里面调用的dllApp::ExitInstance()吧?你的意思是说在::FreeLibrary()之后就先退出辅助线程然后在调用dllApp::ExitInstance这个函数是吗?  
  感谢你的解释,如果有什么可以继续说一下,晚上下班前就结贴了!分数都给你Top

20 楼linur(林子大了,什么鸟都有)回复于 2005-06-27 15:33:13 得分 0

我跟踪的结果显示主线程会先执行runtime函数ExitProcess来释放掉你的MyThread线程,并且释放掉其它资源,然后再调用dllApp::ExitInstance(),这个时候MyThread线程已经不存在了,所以主线程执行  
  bRun   =   false;时没有起作用,从而执行下一句::WaitForSingleObject(hquit,INFINITE)就阻塞了  
  Top

21 楼qianyong325(帝王企鹅)回复于 2005-06-27 17:37:56 得分 0

我如果另外设置一个handle来判断也就是说如果::WaitForSingleObject(hquit,INFINITE)中的hquit是在dll中另外创建的,而不是用pThread->m_hThread,那么我在调试的时候就可以跟踪到线程中::SetEvent(hquit);,在::WaitForSingleObject(hquit,INFINITE);就可以了,我想如果等待pThread->m_hThread就是你说的这种情况了,等下就结贴了,十分感谢你的帮助Top

22 楼qianyong325(帝王企鹅)回复于 2005-06-28 09:01:30 得分 0

昨天后来公司忙,忘了结贴不好意思,马上就结Top

相关问题

  • DLL&线程问题
  • 多线程和DLL
  • Dll、多线程、事件传递
  • 怎么在DLL中使用多线程?
  • 如何在DLL中创建线程?
  • dll中多线程的问题?
  • 讨论:dll和多线程问题!!!
  • 多线程中调用dll的问题。
  • 线程中可以调用DLL吗?
  • 一个关于多线程的小问题,本人给分信誉良好

关键词

  • 线程
  • 函数
  • dll
  • 代码
  • 解决
  • 执行
  • exitinstance
  • hquit
  • brun
  • 退出

得分解答快速导航

  • 帖主:qianyong325
  • linur

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo