各位大侠,用AfxBeginThread创建10个线程,然后用HANDLE hThread[10]分别存储10个AfxBeginThread返回的CWinthread指针的->m_hThread,最后用
dwWaitResult = WaitForMultipleObjects(10,hThread,TRUE,10000);来wait这十个handle,
结果根本不要用1秒钟函数就返回了,而且返回的值在0到10之间,好像是将参数bWaitAll设为FALSE的那种效果,谁能解释这个问题?另外,线程结束后句柄都释放了,这样WaitForMultipleObjects是不是就会出现这个问题?因为我看了以下CWinThread类有个成员
m_bAutoDelete Specifies whether to destroy the object at thread termination.
就是说,线程结束对象被释放。大家都是怎么做的?就是想实现等线程都结束了,再做另一件事的功能。
多谢!!

解决方案 »

  1.   

    dwWaitResult = WaitForMultipleObjects(10,hThread,TRUE,INFINITE);
      

  2.   

    露上兄弟,我设置的是10000毫秒,十秒钟已经足够了,但是结果没有等待上1秒就返回了一个整型的值,用ININITE无限等待结果十一样的,跟这个没关系
      

  3.   

    返回的 dwWaitResult 值是什么?
      

  4.   

    怀疑线程创建不成功,查看一个WaitForMultipleObjects传入的hThread句柄是否均为有效值。
      

  5.   

    dwWaitResult 是在0到10之间
    线程创建肯定成功了,因为我的系统一直在干活呢,而且从任务管理器观察线程数很正常,如果谁做过类似等待demo,希望能给点帮助,多谢!!
      

  6.   

    可以用下面方法试试:
    //初始化:
    HANDLE hEvents[10];
    for (int i = 0; i < 10; i++)
      hEvents[i] = CreateEvent(NULL, FALSE, FALSE, NULL);//线程函数i  (1<=i<=10)
    {
    ...
    //在线程i结束前调用:
    SetEvent(hEvents[i]);
    }//等待前10个线程执行完毕或者10s超时
    dwWaitResult = WaitForMultipleObjects(10,hEvents,TRUE,10000);
      

  7.   

    严重支持此贴!我现在碰到一个几乎完全一样的问题,就是使用
    WaitForMultipleObjects(10,hEvents,TRUE,60000);//hEvents为存放自动重置事件句柄的数组
    的时候,它不会返回WAIT_OBJECT_0,而是返回0到WAIT_OBJECT_0 + 10之间的值。
    后来我跟踪进去的时候,发现在线程函数中执行:BOOL bSet = SetEvent(hEvents[i]);此语句的时候bSet = 0;根据MSDN也就是SetEvent没有成功。请问在那种情况下SetEvent会失败呢?我找了很多地方都找不到这种原因。
    关注
      

  8.   

    刚刚看到了一个详细的WaitForMultipleObjects参数说明:说当第三个参数为True的时候,可以返回0到WAIT_OBJECT_0 + 10之间的值表示等待全部事件已经触发,只是大多数情况下应该为WAIT_OBJECT_0 。
    还有很奇怪的问题,我的这个函数是封装在动态库里面的,在别人的机器上调试可以通过,在我的机器上如果直接调用动态库的话老是在这个WaitForMultipleObjects经常出错,但是如果我把dll的源代码在我的机器上编译一下再调用,却有可以成功,请问谁知道这种情况是怎么回事情啊?
      

  9.   

    Pandona兄弟说得方法我也试过,还是失败,同样的结果
    另外爱神兄弟好像没看懂我我们讨论的问题啊,线程结束了,句柄都释放了,哪里有什么等待可言?
      

  10.   

    Pandona兄弟为啥初始化的时候hEvent为0<i<10,而在SetEvent(hEvents[i]);的时候却编程了1=<i<=10?有什么说法?
      

  11.   

    线程结束后,自动销毁的是CWinThread对象,而不是线程句柄,线程句柄只有在
    ::CloseHandle(hThread)之后才会释放。所以线程结束后,线程变为有信号,你才有可能等待。CWinThread::m_bAutoDelete
    ResSpecifies whether the CWinThread object should be automatically deleted at thread termination. The m_bAutoDelete data member is a public variable of type BOOL.
      

  12.   

    晕。想多了,hollysky(爱神) 说得对。线程句柄在线程执行完后会置为有信号状态。你所说的句柄释放了肯定是指 m_bAutoDelete 设置为 TRUE,实际上它只是 delete CWinThread,而不是关闭线程句柄(CloseHandle)。不相信的话可以在线程处理程序中随机生成一个大一点的随机数,然后用 Sleep 试试。
      

  13.   

    楼上兄弟,你是说线程CWinThread对象被删除后,线程句柄还是可以wait 的,对吧?但是线程句柄就是CWinThread *p的一个成员,跟p->m_bAutoDelete是一样的,p都被删除了,线程句柄肯定也就被删除了,还能用Wait来等待吗?能否给我个小例子我demo一下?多谢!!
    [email protected]
      

  14.   

    你的句柄原来不是保存到 HANDLE hThread[10] 里吗?
      

  15.   

    试试下面这个方法:
    1。AfxBeginThread()//设置CREATE_SUSPENDED标志,使线程挂起
    2。设置m_bAutoDelete为False
    3。保存10个m_hThread到HANDLE hThread[10]中
    4。CWinThread::ResumeThread 启动线程
    5。dwWaitResult = WaitForMultipleObjects(10,hThread,TRUE,10000);
    6。当WaitForMultipleObjects函数返回时,查询10个线程的退出代码:GetExitCodeThread()
    7。手动销毁线程
      

  16.   

    for(int i= 0; i<10; i++)
    {
    hThread[i]=AfxBeginThread((AFX_THREADPROC)WorkerThread,(LPVOID)pParam,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED,NULL);
    hThread[i]->m_bAutoDelete=FALSE;
    hThread[i]->ResumeThread();
    }WaitForMultipleObjects(10,hThread,TRUE,INFINITE);
    for(i=0;i<10;i++)
    CloseHandle(hThread[i]->m_hThread);这种结构就ok了。
      

  17.   

    likongxu(温柔一刀) ( )和betsyalan(alan)的方法,你可以试,应该没有问题.
      

  18.   

    谢谢各位的解答,我回去试试先,但还是有点疑惑,为什么要这样做呢?最后Wait返回后,只是
    CloseHandle(hThread[i]->m_hThread);
    而不删除hThread[i]是否会造成内存泄漏?
      

  19.   

    怎么WaitForMultipleObjects报错了?
    error C2664: 'WaitForMultipleObjects' : cannot convert parameter 2 from 'class CWinThread *[10]' to 'void *const * '我的hThread是这样定义的:CWinThread *hThread[10]
    不行吗?
      

  20.   

    想知道等待线程结束都是这么干的吗?这样好像有问题,我以前运行很好的程序这样改造了一下,结果老报内存越界的问题,coredump了。还有好的办法吗?
      

  21.   

    DWORD WaitForMultipleObjects(
      DWORD nCount,             // number of handles in the handle array
      CONST HANDLE *lpHandles,  // pointer to the object-handle array
      BOOL fWaitAll,            // wait flag
      DWORD dwMilliseconds      // time-out interval in milliseconds
    );
    第二个参数是对象句柄数组而不是线程数组啊,应用用 HANDLE  hThread[10]。
    CloseHandle(hThread[i]->m_hThread);
    后,如果此线程对象的内核计数值减1,如果减1后此值为0的话,系统会自动销毁此线程。
      

  22.   

    CWinThread的析构函数里面调用了CloseHandle().所以你如果在外面要关闭线程句柄,就要注意这个问题了.可能会产生异常哦!!!
      

  23.   

    叫化子兄弟,你说到底改怎么搞呢?我试了上面所有的方法都不行,如果谁有这方面的demo,能否分享一个给我?谢谢:
    [email protected]
      

  24.   

    有一点,搂住存储句柄的时候有没有使用DuplicateHanlde()函数,如果没有,请试试,这个函数的作用可以查MSDN
      

  25.   

    #include <stdio.h>
    #include <TCHAR.h>
    #include <windows.h>DWORD WINAPI ThreadProc(LPVOID lpParameter)
    {
    TCHAR lpszTempBuf[20];
    _stprintf(lpszTempBuf, "%d", (INT)lpParameter);
    MessageBox(NULL, lpszTempBuf, NULL, MB_OK);
    return 0;
    }INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
    {
    HANDLE hThreadArray[10];
    DWORD dwThreadID;
    for (INT i=0; i<10; i++)
    {
    hThreadArray[i] = CreateThread(NULL, 0, ThreadProc, (LPVOID)i, 0, &dwThreadID);
    if (NULL == hThreadArray[i])
    {
    MessageBox(NULL, TEXT("CreateThread Failed"), NULL, MB_OK);
    ExitProcess(0);
    }
    }
    WaitForMultipleObjects(10, hThreadArray, TRUE, INFINITE);
    MessageBox(NULL, TEXT("ALL Thread exit."), NULL, MB_OK);
    return 0;
    }
    只有前10个对话框都弹完了,才弹ALL Thread exit这个对话框.
      

  26.   

    说的不清除,重说:应该使程序运行后,创建了10个线程,每个线程都弹了一个对话框,此时线程在对话框的消息循环上运行,只有你点了[确定]按钮后,线程才退出,此时线程句柄变为有信号状态,所以运行上述程序,你得点了10个对话框后,也就使所有得非主线程都退出后,WaitForMultipleObjects(10, hThreadArray, TRUE, INFINITE);返回,你才能看到MessageBox(NULL, TEXT("ALL Thread exit."), NULL, MB_OK);这个对话框.
      

  27.   

    CreateThread在VC环境中不是安全的,会造成内存泄漏,不知道是不是真的?