WIN32多线程二 用WaitXXX函数等待线程结束

等待线程结束的更好方法是调用API WaitForSigleObject和WaitForMultipleObjects。前者用于等待一个线程由未激发状态变为激发状态,后者用于等待多个线程中全部或多个中的一个由未激发状态变为激发状态。对线程内核对象而言,如果线程在运行,则是未激发状态;如果线程已经退出,则是激发状态。不同内核对象的激发、未激发状态含义有所不同。

DWORD WINAPI WaitForSingleObject(
  __in          HANDLE hHandle,        //等待的内核对象句柄
  __in          DWORD dwMilliseconds    //等待的超时时间
);
函数失败,返回WAIT_FAILED;
等待对象变为激发状态,返回WAIT_OBJECT_O;
等待超时,返回WAIT_TIMEOUT;
一个拥有mutex的线程结束前,没有释放掉mutex,则返回WAIT_ABANDONED.

DWORD WINAPI WaitForMultipleObjects(
  __in          DWORD nCount,        //等待内核对象个数
  __in          const HANDLE* lpHandles,//内核对象数组
  __in          BOOL bWaitAll,        //是否等待所有内核对象,还是等待其中一个变为激发状态就返回
  __in          DWORD dwMilliseconds    //等待的超时时间
);
函数失败,返回WAIT_FAILED;
等待超时,返回WAIT_TIMEOUT;
bWaitAll为TRUE,所有对象变为激发状态,返回WAIT_OBJECT_O;
bWaitAll为FALSE,返回值减去WAIT_OBJECT_O的值就是变为激发状态内核对象在数组中的索引;
如果内核对象中有mutex,返回值可能在WAIT_ABANDONED到WAIT_ABANDONED+nCount-1。

下面是个<<WIN32多线程程序设计>>中用WaitForMultipleObjects实现的简单的线程池的例子,3个线程来完成6个任务。
/*
 * MTVERYFY.h
*/
#pragma comment( lib, 
" USER32 "  )

#include 
< crtdbg.h >
#define  MTASSERT(a) _ASSERTE(a)


#define  MTVERIFY(a) if (!(a)) PrintError(#a,__FILE__,__LINE__,GetLastError())

__inline 
void  PrintError(LPSTR linedesc, LPSTR filename,  int  lineno, DWORD errnum)
{
    LPSTR lpBuffer;
    
char  errbuf[ 256 ];
#ifdef _WINDOWS
    
char  modulename[MAX_PATH];
#else   //  _WINDOWS
    DWORD numread;
#endif   //  _WINDOWS

    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
        
|  FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        errnum,
        LANG_NEUTRAL,
        (LPTSTR)
& lpBuffer,
        
0 ,
        NULL );

    wsprintf(errbuf, 
" \nThe following call failed at line %d in %s:\n\n "
        
"     %s\n\nReason: %s\n " , lineno, filename, linedesc, lpBuffer);
#ifndef _WINDOWS
    WriteFile(GetStdHandle(STD_ERROR_HANDLE), errbuf, strlen(errbuf), 
& numread, FALSE );
    Sleep(
3000 );
#else
    GetModuleFileName(NULL, modulename, MAX_PATH);
    MessageBox(NULL, errbuf, modulename, MB_ICONWARNING
| MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
#endif
    exit(EXIT_FAILURE);
}

#include  < stdio.h >
#include 
< stdlib.h >
#include 
< Windows.h >
#include 
" MTVERIFY.h "

#define  THREAD_POOL_SIZE  3
#define  NUM_TASKS    6

DWORD WINAPI ThreadFunc(LPVOID);

int  main()
{
    HANDLE    hThreads[THREAD_POOL_SIZE];
    
int         i;
    
int         slot  =   0 ;
    DWORD    dwThreadId;
    DWORD    rc;

    
for  ( i = 0 ; i < NUM_TASKS; i ++  )
    {
        
if  ( i  >=  THREAD_POOL_SIZE )
        {
            rc 
=  WaitForMultipleObjects(THREAD_POOL_SIZE, hThreads, FALSE, INFINITE);
            slot 
=  rc  -  WAIT_OBJECT_0;
            MTVERIFY( 
0 <= slot  &&  slot < THREAD_POOL_SIZE );
            printf(
" Slot %d terminated.\n " ,slot);
            MTVERIFY( CloseHandle(hThreads[slot]) );
        }

        MTVERIFY( hThreads[slot
++ =  CreateThread(NULL,  0 , ThreadFunc, (LPVOID)slot,  0 & dwThreadId) );
        printf(
" Launched thread #%d (slot %d).\n " , i, slot);
    }

    rc 
=  WaitForMultipleObjects(THREAD_POOL_SIZE, hThreads, TRUE, INFINITE);
    MTVERIFY( WAIT_OBJECT_0
<= rc  &&  rc < WAIT_OBJECT_0 + THREAD_POOL_SIZE );
    
    
for  ( slot = 0 ; slot < THREAD_POOL_SIZE; slot ++  )
    {
        MTVERIFY( CloseHandle(hThreads[slot]) );
    }

    
return  EXIT_SUCCESS;
}


DWORD WINAPI ThreadFunc(LPVOID n)
{
    srand( GetTickCount() );

    Sleep( (rand()
% 10 ) * 800 + 500  );
    printf(
" Slot %d idle.\n " , n);

    
return  (DWORD)n;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值