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

一道高难度的面试题(很怪)

楼主lcs1980(lcs)2005-03-01 19:47:00 在 VC/MFC / 网络编程 提问

//临界区变量  
  CRITICAL_SECTION   m_sect;  
   
  int   iCount   =   0;  
  void   Test(LPVOID   iThread)  
  {  
  int   Thread   =   (int   )   iThread;  
  for(int   i   =   1   ;   i<=10   ;i   ++)  
  {  
  ::EnterCriticalSection(&m_sect);  
   
  //Sleep(10);加上这条语句为什么结果不同  
   
  int   j=iCount;  
  iCount++;  
   
  printf("Thread%d   :   icount=   %d   \n",Thread,iCount);  
   
  ::LeaveCriticalSection(&m_sect);  
  }  
  }  
   
  //创建临界区  
  InitializeCriticalSection(&m_sect);  
  //创建线程  
  HANDLE   hThread[3];  
  CWinThread*   pT1=AfxBeginThread((AFX_THREADPROC)Test,(void*)1);  
  CWinThread*   pT2=AfxBeginThread((AFX_THREADPROC)Test,(void*)2);  
  CWinThread*   pT3=AfxBeginThread((AFX_THREADPROC)Test,(void*)3);  
   
  hThread[0]=pT1->m_hThread;  
  hThread[1]=pT2->m_hThread;  
  hThread[2]=pT3->m_hThread;  
   
  WaitForMultipleObjects(3,hThread,TRUE,INFINITE);  
   
  问题  
   
  为什么结果不是30  
  问题点数:0、回复次数:42Top

1 楼Practise_Think(时代“过客”)回复于 2005-03-01 21:05:45 得分 0

为什么加了Sleep()之后就不同??   没运行过,我也不明白!!!Top

2 楼lcs1980(lcs)回复于 2005-03-01 21:36:54 得分 0

那运行一下吧,  
   
  那你认为答案是多少?Top

3 楼ficher(小鱼儿)回复于 2005-03-01 22:11:11 得分 0

markTop

4 楼wwwllg(野蛮人)回复于 2005-03-01 23:03:28 得分 0

肯定是30.Top

5 楼duxianghe( dux++ )回复于 2005-03-01 23:11:12 得分 0

不太理解  
  应该是30吧Top

6 楼Caps77(厉兵秣马)回复于 2005-03-01 23:42:03 得分 0

没有sleepC41.7   256m机器为20,有sleep为30  
   
  猜解:   主线程在第三个线程启动后,进入函数体循环前退出了,第三个辅助线程来不及打印就退  
   
  出了,在程序末尾加个sleep(1),既为30  
   
  纯属猜测,关注正解!Top

7 楼baojian88888(机器人)回复于 2005-03-02 08:26:07 得分 0

gzTop

8 楼wizard13(我也要学习....)回复于 2005-03-02 08:37:28 得分 0

不懂,MARKTop

9 楼alec626(月吻长河Blog:spaces.msn.com/filebase)回复于 2005-03-02 08:58:05 得分 0

MARKTop

10 楼zhouhuaikun(怀空)回复于 2005-03-02 09:01:12 得分 0

markTop

11 楼vcleaner(我没当大哥很久了.......)回复于 2005-03-02 09:20:43 得分 0

呵呵,通过对话框的程序测试,在P4,2.1,256M机器上最终的结果都是30。没有什么不同的。Top

12 楼Magnus(小楼一夜听春雨)回复于 2005-03-02 10:06:23 得分 0

console下就和楼主所说一致。Top

13 楼babam()回复于 2005-03-02 10:06:45 得分 0

我在命令行下运行也是30.   vc6.0;win2000;   sleep(101);配置p4   2.4g,512mTop

14 楼mycs2005()回复于 2005-03-02 10:17:36 得分 0

我把其中的中间结果打印出来       结果如下  
   
  CRITICAL_SECTION   m_sect;  
  int   iCount   =   0;  
  CString   str;  
   
  DWORD   Test(LPVOID   iThread)  
  {  
  int   Thread   =   (int   )   iThread;  
  CFile   f;  
  f.Open("c:\\olio.txt",CFile::modeWrite);  
  f.SeekToEnd();  
  CString   s;  
  s.Format("-------------->thread:%d->   %d\r\n",Thread,iCount);  
  f.Write(s.GetBuffer(0),s.GetLength());  
  f.Close();  
   
  for(int   i   =   1   ;   i<=10   ;i   ++)  
  {  
  ::EnterCriticalSection(&m_sect);  
   
  //Sleep(10);//加上这条语句为什么结果不同  
   
   
  int   j=iCount;  
   
  CString   s;  
  s.Format("thread:%d->   %d\r\n",Thread,iCount);  
  str   +=   s;  
   
  iCount++;  
   
   
  ::LeaveCriticalSection(&m_sect);  
  }  
  return   Thread;  
  }  
   
  void   CZTst10View::OnT1()    
  {  
  InitializeCriticalSection(&m_sect);  
  //创建线程  
  HANDLE   hThread[3];  
  CWinThread*   pT1=AfxBeginThread((AFX_THREADPROC)Test,(void*)1);  
  CWinThread*   pT2=AfxBeginThread((AFX_THREADPROC)Test,(void*)2);  
  CWinThread*   pT3=AfxBeginThread((AFX_THREADPROC)Test,(void*)3);  
   
  hThread[0]=pT1->m_hThread;  
  hThread[1]=pT2->m_hThread;  
  hThread[2]=pT3->m_hThread;  
   
  CString   s;  
  CString   s1;  
  DWORD   dwret   =   -1;  
  ::GetExitCodeThread(hThread[0],&dwret);  
  s1.Format("exit:%d",dwret);  
  s   +=   s1;  
   
  ::GetExitCodeThread(hThread[1],&dwret);  
  s1.Format("exit:%d",dwret);  
  s   +=   s1;  
   
  ::GetExitCodeThread(hThread[2],&dwret);  
  s1.Format("exit:%d",dwret);  
  s   +=   s1;  
   
  WaitForMultipleObjects(3,hThread,TRUE,INFINITE);  
   
  s1.Format("res:%d",iCount);  
  s+=s1;  
  iCount   =   0;  
  AfxMessageBox(s);  
   
  CFile   f;  
  f.Open("c:\\olio.txt",CFile::modeWrite);  
  f.SeekToEnd();  
  f.Write(str.GetBuffer(0),str.GetLength());  
  f.Close();  
  }  
   
   
   
  -------------->thread:1->   0                           //第一个线程进入时  
  -------------->thread:2->   10                         //第二个线程进入时  
  -------------->thread:3->   0                           //第三个线程进入时       奇怪这里怎么是   0应该是20啊  
  thread:1->   0  
  thread:1->   1  
  thread:1->   2  
  thread:1->   3  
  thread:1->   4  
  thread:1->   5  
  thread:1->   6  
  thread:1->   7  
  thread:1->   8  
  thread:1->   9  
  thread:2->   10  
  thread:2->   11  
  thread:2->   12  
  thread:2->   13  
  thread:2->   14  
  thread:2->   15  
  thread:2->   16  
  thread:2->   17  
  thread:2->   18  
  thread:2->   19  
  thread:3->   0  
  thread:3->   1  
  thread:3->   2  
  thread:3->   3  
  thread:3->   4  
  thread:3->   5  
  thread:3->   6  
  thread:3->   7  
  thread:3->   8  
  thread:3->   9  
   
  期待高手  
  Top

15 楼mycs2005()回复于 2005-03-02 10:18:10 得分 0

忘了说结果是20Top

16 楼wxdvc(csdn)回复于 2005-03-02 10:49:20 得分 0

加SLEEP==30  
  不加==20  
  我靠,期待高手.Top

17 楼wxdvc(csdn)回复于 2005-03-02 11:13:12 得分 0

经过多次测试,同意Caps77(厉兵秣马)的说法.Top

18 楼ndy_w(carpe diem)回复于 2005-03-02 11:22:31 得分 0

好玩...研究...  
  不加Sleep,在  
  hThread[0]=pT1->m_hThread;  
  hThread[1]=pT2->m_hThread;  
  hThread[2]=pT3->m_hThread;  
  时,有的线程已经结束,CWinThread会改变m_hThread。因此WaitForMultipleObjects失效。  
  如果  
  hThread[0]=(HANDLE)_beginthread(Test,   0,   (void*)1);  
  hThread[1]=(HANDLE)_beginthread(Test,   0,   (void*)2);  
  hThread[2]=(HANDLE)_beginthread(Test,   0,   (void*)3);  
  即时不Sleep也不会错。Top

19 楼vcleaner(我没当大哥很久了.......)回复于 2005-03-02 11:44:18 得分 0

再次测试,控制台程序,在P4,2.1,256M机器上最终的结果都是30。没有什么不同的。Top

20 楼vcleaner(我没当大哥很久了.......)回复于 2005-03-02 11:46:59 得分 0

错了,是一个20,一个30。学习中。。。。。Top

21 楼nlstone(天外流星)回复于 2005-03-02 11:59:16 得分 0

同意楼上,这里线程结束后CWinThread会改变m_hThread,使之失效,继而wait失效  
  之所以没有打出30是因为第三个线程还来不及打印,程序就已经退出了  
  Top

22 楼ndy_w(carpe diem)回复于 2005-03-02 12:00:32 得分 0

问题应该是在AfxBeginThread上。创建第三个线程时,第一个线程结束了,AfxBeginThread返回pT3   ==   pT1Top

23 楼ppchen(韦古)回复于 2005-03-02 12:19:31 得分 0

C是没有进程和线程的概念。  
  C对多执行流的唯一支持是volatile。  
  int   iCount   =   0;   -->   int   iCount   =   0;  
  不想多说了,自己去查查volatile。  
  Top

24 楼ppchen(韦古)回复于 2005-03-02 12:20:29 得分 0

int   iCount   =   0;   -->   volatile   int   iCount   =   0;  
  Top

25 楼little_duck(小鸭子)回复于 2005-03-02 12:55:49 得分 0

我经过反复测试   我的结果是30   不知道你为什么   我VC6.0   系统XPTop

26 楼wbusy(Woods)回复于 2005-03-02 13:32:09 得分 0

个人觉得是由于互斥和同步不同的原因,因为上面的CS只能保证互斥,而不能保证同步。  
  我把代码做了一点修改如下:  
  //  
  CCriticalSection g_cs;  
  int g_iCounter   =   0;  
  CString g_str;  
   
  typedef   enum{  
  READ   =   1,  
  ADD,  
  SUB  
  }ACCESS;  
   
  int AccessCounter(ACCESS   acc,   int   iThread   =   0)  
  {  
  CSingleLock   lock(&g_cs);  
  lock   .Lock();  
  CString   ss;  
                    int   iTemp;  
  switch(acc)  
  {  
  case   ADD:  
  g_iCounter   ++;  
  ss.Format("Thread   %d   ADD:   %d\r\n",iThread,   g_iCounter);  
  g_str   +=   ss;  
  break;  
  case   SUB:  
  g_iCounter   --;  
  ss.Format("Thread   %d   SUB:   %d\r\n",iThread,   g_iCounter);  
  g_str   +=   ss;  
  break;  
  case   READ:  
  ss   .Format("Thread   %d   Entered:   %d\r\n",   iThread,   g_iCounter);  
  g_str   +=   ss;  
  break;  
  }  
                    iTemp   =   g_iCounter;  
  lock   .Unlock();  
  return   iTemp;  
  }  
   
  UINT Test(LPVOID   lpvoid)  
  {  
  int   Thread   =   (int   )   lpvoid;  
   
  AccessCounter(READ,   Thread);  
  for(int   i   =   1   ;   i<=10   ;i   ++)  
  {  
  //Sleep(GetTickCount()   %   100);//加上这条语句为什么结果不同  
   
  AccessCounter(ADD,   Thread);  
  }  
  return   Thread;  
  }  
   
  void   CTestDlg::OnBnClickedOk()  
  {  
  //   TODO:   在此添加控件通知处理程序代码  
  g_iCounter   =   0;  
  g_str   =   _T("");  
  //创建线程  
  HANDLE   hThread[3];  
  CWinThread*   pT1=AfxBeginThread((AFX_THREADPROC)Test,(void*)1,   THREAD_PRIORITY_NORMAL,   0,   CREATE_SUSPENDED);  
  CWinThread*   pT2=AfxBeginThread((AFX_THREADPROC)Test,(void*)2,   THREAD_PRIORITY_NORMAL,   0,   CREATE_SUSPENDED);  
  CWinThread*   pT3=AfxBeginThread((AFX_THREADPROC)Test,(void*)3,   THREAD_PRIORITY_NORMAL,   0,   CREATE_SUSPENDED);  
   
  ASSERT_VALID(pT1);  
  ASSERT_VALID(pT2);  
  ASSERT_VALID(pT3);  
  hThread[0]=pT1->m_hThread;  
  hThread[1]=pT2->m_hThread;  
  hThread[2]=pT3->m_hThread;  
   
  pT1   ->ResumeThread();  
  pT2   ->ResumeThread();  
  pT3   ->ResumeThread();  
   
  WaitForMultipleObjects(3,hThread,TRUE,INFINITE);  
   
  CString   s;  
  CString   s1;  
  DWORD   dwret   =   -1;  
  ::GetExitCodeThread(hThread[0],&dwret);  
  s1.Format("exit:%d   ",dwret);  
  s   +=   s1;  
   
  ::GetExitCodeThread(hThread[1],&dwret);  
  s1.Format("exit:%d   ",dwret);  
  s   +=   s1;  
   
  ::GetExitCodeThread(hThread[2],&dwret);  
  s1.Format("exit:%d   ",dwret);  
  s   +=   s1;  
   
  s1.Format("Counter   after   3   threads   exited:   %d",   AccessCounter(READ));  
  s+=s1;  
  AfxMessageBox(s);  
   
  g_str   +=   s;  
   
  CFile   f;  
  f.Open("D:\\olio.txt",CFile::modeWrite   |   CFile   ::modeCreate);  
  f.Write(g_str.GetBuffer(0),   g_str.GetLength());  
  f.Close();  
  }  
  测试结果(随机的)分别如下:  
  1)没有Sleep  
  Thread   3   Entered:   0  
  Thread   3   ADD:   1  
  Thread   3   ADD:   2  
  Thread   3   ADD:   3  
  Thread   3   ADD:   4  
  Thread   3   ADD:   5  
  Thread   3   ADD:   6  
  Thread   3   ADD:   7  
  Thread   3   ADD:   8  
  Thread   3   ADD:   9  
  Thread   3   ADD:   10  
  Thread   1   Entered:   10  
  Thread   1   ADD:   11  
  Thread   1   ADD:   12  
  Thread   1   ADD:   13  
  Thread   1   ADD:   14  
  Thread   1   ADD:   15  
  Thread   1   ADD:   16  
  Thread   1   ADD:   17  
  Thread   1   ADD:   18  
  Thread   1   ADD:   19  
  Thread   1   ADD:   20  
  Thread   2   Entered:   20  
  Thread   2   ADD:   21  
  Thread   2   ADD:   22  
  Thread   2   ADD:   23  
  Thread   2   ADD:   24  
  Thread   2   ADD:   25  
  Thread   2   ADD:   26  
  Thread   2   ADD:   27  
  Thread   2   ADD:   28  
  Thread   2   ADD:   29  
  Thread   2   ADD:   30  
  Thread   0   Entered:   30  
  exit:-1   exit:-1   exit:-1   Counter   after   3   threads   exited:   30  
   
  2)有Sleep  
  Thread   3   Entered:   0  
  Thread   1   Entered:   0  
  Thread   2   Entered:   0  
  Thread   3   ADD:   1  
  Thread   1   ADD:   2  
  Thread   2   ADD:   3  
  Thread   3   ADD:   4  
  Thread   1   ADD:   5  
  Thread   2   ADD:   6  
  Thread   3   ADD:   7  
  Thread   1   ADD:   8  
  Thread   2   ADD:   9  
  Thread   3   ADD:   10  
  Thread   3   ADD:   11  
  Thread   3   ADD:   12  
  Thread   3   ADD:   13  
  Thread   1   ADD:   14  
  Thread   2   ADD:   15  
  Thread   3   ADD:   16  
  Thread   1   ADD:   17  
  Thread   2   ADD:   18  
  Thread   3   ADD:   19  
  Thread   3   ADD:   20  
  Thread   1   ADD:   21  
  Thread   2   ADD:   22  
  Thread   1   ADD:   23  
  Thread   2   ADD:   24  
  Thread   1   ADD:   25  
  Thread   2   ADD:   26  
  Thread   1   ADD:   27  
  Thread   2   ADD:   28  
  Thread   1   ADD:   29  
  Thread   2   ADD:   30  
  Thread   0   Entered:   30  
  exit:-1   exit:-1   exit:-1   Counter   after   3   threads   exited:   30  
   
  上面的结果应该可以说明问题。Top

27 楼michael1081(云飞扬)回复于 2005-03-02 13:35:57 得分 0

不懂,gzTop

28 楼windbells(风铃)回复于 2005-03-02 14:02:55 得分 0

这个问题你只要研究一下MFC的源码就明白了AfxBeginThread调用后,会创建一个CWinThread对象,然后用beginthreadex创建一个线程,线程创建成功后,返回CWinThread指针。  
  问题就出在MFC的内部处理上,在  
  UINT   APIENTRY   _AfxThreadEntry(void*   pParam)  
  的函数结尾处会调用  
  AfxEndThread(nResult);  
  而  
  void   AFXAPI   AfxEndThread(UINT   nExitCode,   BOOL   bDelete)  
  {  
  #ifndef   _MT  
  nExitCode;  
  bDelete;  
  #else  
  //   remove   current   CWinThread   object   from   memory  
  AFX_MODULE_THREAD_STATE*   pState   =   AfxGetModuleThreadState();  
  CWinThread*   pThread   =   pState->m_pCurrentWinThread;  
  if   (pThread   !=   NULL)  
  {  
  ASSERT_VALID(pThread);  
  ASSERT(pThread   !=   AfxGetApp());  
   
  //   cleanup   OLE   if   required  
  if   (pThread->m_lpfnOleTermOrFreeLib   !=   NULL)  
  (*pThread->m_lpfnOleTermOrFreeLib)(TRUE,   FALSE);  
   
  if   (bDelete)  
  pThread->Delete();  
  pState->m_pCurrentWinThread   =   NULL;  
  }  
   
  //   allow   cleanup   of   any   thread   local   objects  
  AfxTermThread();  
   
  //   allow   C-runtime   to   cleanup,   and   exit   the   thread  
  _endthreadex(nExitCode);  
  #endif   //!_MT  
  }  
   
  bDelete缺省是TRUE  
  所以会调用CWinThread的delete   函数  
  void   CWinThread::Delete()  
  {  
  //   delete   thread   if   it   is   auto-deleting  
  if   (m_bAutoDelete)  
  delete   this;  
  }  
   
  m_bAutoDelete缺省也是TRUE  
  所以执行的最后CwinThread会把自身删除掉,包括关掉线程句柄。  
   
  直接用SDK开发,就没有这个问题了。如果用MFC的话,可以这么处理  
  InitializeCriticalSection(&m_sect);  
  //创建线程  
  HANDLE   hThread[3];  
  CWinThread*   pT1=AfxBeginThread((AFX_THREADPROC)Test,(void*)1,0,0,CREATE_SUSPENDED);  
  CWinThread*   pT2=AfxBeginThread((AFX_THREADPROC)Test,(void*)2,0,0,CREATE_SUSPENDED);  
  CWinThread*   pT3=AfxBeginThread((AFX_THREADPROC)Test,(void*)3,0,0,CREATE_SUSPENDED);  
  pT1->m_bAutoDelete   =   FALSE;  
  pT2->m_bAutoDelete   =   FALSE;  
  pT3->m_bAutoDelete   =   FALSE;  
   
  hThread[0]=pT1->m_hThread;  
  hThread[1]=pT2->m_hThread;  
  hThread[2]=pT3->m_hThread;  
  pT1->ResumeThread();  
  pT2->ResumeThread();  
  pT3->ResumeThread();  
  DWORD   dwRet   =   WaitForMultipleObjects(3,hThread,TRUE,INFINITE);  
  delete   pT1;  
  delete   pT2;  
  delete   pT3;  
   
   
   
   
   
   
  Top

29 楼guihui5460( flystar)回复于 2005-03-02 15:27:22 得分 0

WaitForMultipleObjects(3,hThread,TRUE,INFINITE);  
  这函数返回是失败的,我想这是原因所在,当这个函数返回返加时,thread3还没有运行  
  而下面的s1.Format("res:%d",iCount);  
  s+=s1;  
  iCount   =   0;  
  AfxMessageBox(s);  
  所以会出现那样的结果,当运行第三线程时iCount已经为0了,  
  我自己认为WaitForMultipleObjects(3,hThread,TRUE,INFINITE);  
  之所以会返回失败是因为当调用它时,thread1,thread2,已运行结束,而且线程运行完这后自动删除了,所以会返回失败,而加Sleep(10)Top

30 楼guihui5460( flystar)回复于 2005-03-02 15:28:53 得分 0

后,WaitForMultipleObjects(3,hThread,TRUE,INFINITE);运行时,thread1,thread2还没有运行结束,对象存在,返回成功,所以结果是正确的  
  Top

31 楼andyfr1210(华仔)回复于 2005-03-02 17:36:38 得分 0

在控制台下测试,不管加不加SLEEP都返回30  
  不知道是不是我的电脑比较烂的原因!  
  Top

32 楼SInoyew(天行杨)回复于 2005-03-02 18:20:51 得分 0

哦?Top

33 楼Featured(我握着爱情的门票静静排队……)回复于 2005-03-02 19:08:30 得分 0

天哪,我晕了  
  怎么我拷贝代码建立工程Build发生错误,  
  如下:  
   
   
  #include   <stdio.h>  
   
   
  CRITICAL_SECTION   m_sect;  
   
  int   iCount   =   0;  
   
  void   Test(LPVOID   iThread)  
  {  
  int   Thread   =   (int   )   iThread;  
  for(int   i   =   1   ;   i<=10   ;i   ++)  
  {  
  ::EnterCriticalSection(&m_sect);  
   
  //Sleep(10);加上这条语句为什么结果不同  
   
  int   j=iCount;  
  iCount++;  
   
  printf("Thread%d   :   icount=   %d   \n",Thread,iCount);  
   
  ::LeaveCriticalSection(&m_sect);  
  }  
  }  
     
   
  void   main()  
  {    
  //////////////////////////////////////////////////////////  
   
   
  //创建临界区  
  InitializeCriticalSection(&m_sect);  
  //创建线程  
  HANDLE   hThread[3];  
  CWinThread*   pT1=AfxBeginThread((AFX_THREADPROC)Test,(void*)1);  
  CWinThread*   pT2=AfxBeginThread((AFX_THREADPROC)Test,(void*)2);  
  CWinThread*   pT3=AfxBeginThread((AFX_THREADPROC)Test,(void*)3);  
   
  hThread[0]=pT1->m_hThread;  
  hThread[1]=pT2->m_hThread;  
  hThread[2]=pT3->m_hThread;  
   
  WaitForMultipleObjects(3,hThread,TRUE,INFINITE);  
   
   
   
  }  
  Top

34 楼Anthony88(Anthony)回复于 2005-03-02 20:31:24 得分 0

太难了,MFC太难了,放弃了  
  也看不懂了Top

35 楼redchina(风清云淡)回复于 2005-03-02 21:17:39 得分 0

for(int   i   =   1   ;   i<=10   ;i   ++)  
  {  
  ::EnterCriticalSection(&m_sect);  
   
  //Sleep(10);加上这条语句为什么结果不同  
   
  int   j=iCount;  
  iCount++;  
   
  printf("Thread%d   :   icount=   %d   \n",Thread,iCount);  
   
  ::LeaveCriticalSection(&m_sect);  
  }  
  修改成下边的呢?  
   
  ::EnterCriticalSection(&m_sect);  
  for(int   i   =   1   ;   i<=10   ;i   ++)  
  {  
   
   
  //Sleep(10);加上这条语句为什么结果不同  
   
  int   j=iCount;  
  iCount++;  
   
  printf("Thread%d   :   icount=   %d   \n",Thread,iCount);  
   
   
  }  
  ::LeaveCriticalSection(&m_sect);Top

36 楼redchina(风清云淡)回复于 2005-03-02 21:19:52 得分 0

你所列出的代码事实上线程切换会非常频繁。Top

37 楼zengwujun(月之海 为linux入门奋斗100天)回复于 2005-03-03 10:37:52 得分 0

markTop

38 楼sashilover(闭门思过中。。。。)回复于 2005-03-03 13:10:17 得分 0

markTop

39 楼winthegame(120斤重的大青蛙)回复于 2005-03-03 14:14:51 得分 0

要有根据,最简单就是加些调试!  
   
  DWORD   dwResult   =   WaitForMultipleObjects(3,hThread,TRUE,INFINITE);  
  printf("%d\n",   dwResult);  
  printf("%d",   GetLastError());  
   
  可以明显看出WaitForMultipleObjects返回是以失效来结束的,而并非是返回成功。而GetLastError也返回错误。查查错误原因,就清楚了,由于没有Sleep的存在,线程循环几乎是以单线程似的方式串行运行,在第三个线程压根没有分配到时间启动前,时间已经轮循到了主线程那里,这时执行  
  WaitForMultipleObjects(3,hThread,TRUE,INFINITE);  
  WaitForMultipleObjects立即发现分配过来的第三个线程句柄为无效句柄,于是不作等待,立即返回,  
  就这样默默的结束了整个程序,留下了一屁股后遗症。  
   
  所以找到症结,要正确,在任何线程中加Sleep均可,既是在做WaitForMultipleObjects   之前就等待即可,或者干脆点说,把主线程代码量加大,只要保证线程在启动完毕前,主线程不莫名其妙的Over就可以了。Top

40 楼stonex_2000(三棱镜)回复于 2005-03-03 15:13:43 得分 0

正如ndy_w(carpe   diem)说的那样,  
  有可能在运行到给数组赋值之前线程就运行完毕了.  
   
  如下就不管是否sleep就没问题了.  
  hThread[0]   =   CreateThread(NULL,   0,   (LPTHREAD_START_ROUTINE)Test,   (void*)1,   0,   NULL);  
  hThread[1]   =   CreateThread(NULL,   0,   (LPTHREAD_START_ROUTINE)Test,   (void*)2,   0,   NULL);  
  hThread[2]   =   CreateThread(NULL,   0,   (LPTHREAD_START_ROUTINE)Test,   (void*)3,   0,   NULL);Top

41 楼dongfa(一桶江湖( http://www.codelive.net ))回复于 2005-03-03 15:54:04 得分 0

因为启动线程是异步的,如果运行的太快,线程还没有启动完成时,线程HANDLE肯定是无效的,因此在执行WaitForMultipleObjects时变反回了。Top

42 楼shizhen(失贞)回复于 2005-03-03 18:47:17 得分 0

执行到CWinThread*   pT3=AfxBeginThread((AFX_THREADPROC)Test,(void*)3);时第一个线程已经执行完,并且释放了所用的内存,pT3这时正好申请到了pT1用过的内存.地址相同.  
  到WaitForMultipleObjects,检查到两个相同地址的句柄值,即而失败返回Top

相关问题

  • 高难度问题。。。
  • 高难度问题
  • 高难度问题!!!~~~~~
  • 高难度问题
  • 高难度问题
  • 高难度问题
  • 高难度问题
  • 高难度问题:ORACLE PASSWORD
  • DCOM的高难度问题?
  • 高难度的算法题!

关键词

  • 线程
  • 函数
  • hthread
  • dwret
  • pt
  • cwinthread
  • icount
  • ithread
  • getexitcodethread
  • afxbeginthread

得分解答快速导航

  • 帖主:lcs1980

相关链接

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

广告也精彩

反馈

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