线程的等待

一. 一般等待

1. sleep()

在操作系统中止此线程动作,直到渡过某个时间之后才恢复。

VOID Sleep(
  DWORD dwMilliseconds   // sleep time
);

实际上你不可能事先知道什么事情要等待多久,比如一个高优先级线程抢占执行的话,这个时间将变得不可预测。

要注意的是,Sleep( ),会放弃系统分配的剩余的时间片,这样 OS 就能更好的服务其他的进程和线程了。

2. busy loop

for (;;)
{
    GetExitCodeThread(hThrd1, &exitCode1);
    
    if ( exitCode1 == STILL_ACTIVE )
        puts("Thread 1 is still running!");
}
忙等,是很浪费CPU时间的!因为 for( ) 在一直工作。

二. 等待线程结束

//等待一个线程结束
DWORD WaitForSingleObject(
  HANDLE hHandle,        // handle to object
  DWORD dwMilliseconds   // 最长的等待时间,INFINITE 表示无穷等待
);
// 返回值:
// WAIT_FAILED,    表示函数失败
// WAIT_OBJECT_0,    表示等待的核心对象变成激发状态
// WAIT_TIMEOUT,    表示核心对象在变成激发状态之前,时间终了了


//等待多个线程结束
DWORD WaitForMultipleObjects(
  DWORD nCount,             // handles 数组元素个数
  CONST HANDLE *lpHandles,  // handles 数组
  BOOL bWaitAll,            // TRUE 表示所有的handles都必须激发,此函数才得以返回
  DWORD dwMilliseconds      // 终了时间
);
// 返回值:
// WAIT_TIMEOUT,	时间终了
// WAIT_FAILED,	表示函数失败
// bWaitAA == TRUE,	返回值是 WAIT_OBJECT_0
// bWaitAA == FASLE,	返回值减去 WAIT_OBJECT_0,就表示数组中的哪一个 handle 被激发了
// WAIT_TIMEOUT,	表示核心对象在变成激发状态之前,时间终了了
说明:

WaitForXXXObject( ),相当于一个新版的 sleep( ),它能够在某个线程结束时被调用。

WaitForXXXObject( ),像 sleep( )一样,只会占用很少的CPU,不会出现忙等现象,所以效率会高很多。

WaitForXXXObject( ),到底在等什么?其实它等待的是一些对象被激发

三. 被激发对象

可被 WaitForXXXObject( )使用的核心对象有两种状态:激发与未激发,WaitForXXXObject( ) 在目标变成激发状态时才返回。

比如:

Thread 当线程结束时,线程对象即被激发

Process 当进程结束时,进程对象即被激发

Event 直接受控于 SetEvent(),PulseEvent(),ResetEvent()三个函数

Mutex 如果 mutex 没有被任何线程拥有,它就处于激发状态

Semaphore 当计数器内容大于0时,semaphore处于激发状态

当出现以上对象动作时,线程对象就会被激发,此时 WaitForXXXObject( ) 就能返回。

四. 示例代码

最多用三个线程来完成六项工作

#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>


DWORD WINAPI ThreadFunc(LPVOID);

#define THREAD_POOL_SIZE 3            //线程池大小为3
#define MAX_THREAD_INDEX THREAD_POOL_SIZE-1
#define NUM_TASKS 6                //共有6个任务

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

    for (i=1; i<=NUM_TASKS; i++)
    {
        /* 当用完线程池里所有的线程时,要等待其它线程结束 */
        if (i > THREAD_POOL_SIZE)
        {
            /* 等待一个线程结束 */
            rc = WaitForMultipleObjects(
                THREAD_POOL_SIZE,
                hThrds,
                FALSE,
                INFINITE );
            slot = rc - WAIT_OBJECT_0;

            printf("Slot %d terminated\n", slot );

            CloseHandle(hThrds[slot]);
        }

        /* 创建 6 个线程 */
        hThrds[slot] = CreateThread(NULL,
            0,
            ThreadFunc,
            (LPVOID)slot,
            0,
            &threadId );

        printf("Launched thread #%d (slot %d)\n", i, slot);

        slot++;
    }

    /* 等待所有的线程结束 */
    rc = WaitForMultipleObjects(
        THREAD_POOL_SIZE,
        hThrds,
        TRUE,
        INFINITE );
   
    for (slot=0; slot<THREAD_POOL_SIZE; slot++)
        CloseHandle(hThrds[slot]);

    printf("All slots terminated\n");

    return EXIT_SUCCESS;
}

/*
 * This function just calls Sleep for
 * a random amount of time, thereby
 * simulating some task that takes time.
 *
 * The param "n" is the index into
 * the handle array, kept for informational
 * purposes.
 */
DWORD WINAPI ThreadFunc(LPVOID n)
{
    srand( GetTickCount() );

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

说明:

代码是《Win32多线程程序设计》上的,很经典。


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值