Win32 多线程程序设计(5)— 线程的控制

2011 年 09 月 12 日 by name5566

干净的终止一个线程

之前我们介绍过 ExitThread API(http://name5566.com/185.html),其用于结束当前线程。区别于 ExitThread() 我们还有一个类似的 API — TerminateThread() 可以用于结束其他线程:

// 函数执行成功返回 TRUE,否则返回 FALSE
BOOL TerminateThread(
    // 需要结束的目标线程
    HANDLE hThread,
    // 指定线程的退出码
    DWORD dwExitCode
);

要注意,TerminateThread 函数建议不使用,因为其会导致被结束线程无法进行清理工作。终止一个线程更好的做法是:对线程设置一个标志,此标志用于表示线程是否需要结束:

DWORD WINAPI ThreadFunc(LPVOID p)
{
    while (true)
    {
        // 进行一些工作

        // 这里 hRequestExitEvent 是一个 Events 句柄
        // 前面谈到过(http://name5566.com/745.html)
        // 我们可以设置 Wait... 的最长等待时间为 0 用以检查内核对象的状态
        //
        // 其他线程通过设置此 Event 对象为 signaled 状态来结束此线程
        // 内核对象为 signaled 状态时,WaitForSingleObject 函数返回 WAIT_OBJECT_0
        // 这里不一定要使用 Event 对象,但由于 Event 对象是内核对象
        // 因此在一些场合这里可以使用 WaitForMultipleObjects 来同时等待其他内核对象及线程退出请求
        if (::WaitForSingleObject(hRequestExitEvent, 0) != WAIT_TIMEOUT)
        {
            return (DWORD)-1;
        }
    }

    return 0;
}
线程的优先级(Thread Priority)

Win32 有所谓的优先权的概念,较高优先级的线程必然获得较多的 CPU 时间。优先权以一个数值表示,值为 0 ~ 31。

进程的优先级类型(Priority class)决定了进程的重要性,Win32 提供了 4 种优先级类型:

  1. HIGH_PRIORITY_CLASS — 权值 13
    任务管理器就是使用 HIGH_PRIORITY_CLASS,即使系统很忙碌的情况下,它常常会对操作有反应
  2. IDLE_PRIORITY_CLASS — 权值 4
    有时候我们期望程序在 CPU 空闲下来的时候才执行,这个时候使用 IDLE_PRIORITY_CLASS 就很合适
  3. NORMAL_PRIORITY_CLASS — 权值 7 or 8
    一般的应用程序都是使用这个类型
  4. REALTIME_PRIORITY_CLASS — 权值 24
    进程设置为此优先权类型,那么它将优于内核进程和设备驱动进程,不要对 GUI 程序或者典型的服务器程序使用此优先级类型

Windows 的相关 API 为 SetPriorityClass() 和 GetPriorityClass()

线程的优先级等级(Priority level)决定了同一个进程中的各个线程的相对重要性,实际上线程的优先级等级是对进程的优先级类型的一个修改,Win32 提供了 7 种优先级等级:

  1. THREAD_PRIORITY_HIGHEST — 权值 +2
  2. THREAD_PRIORITY_ABOVE_NORMAL — 权值 +1
  3. THREAD_PRIORITY_NORMAL — 权值 +0
  4. THREAD_PRIORITY_BELOW_NORMAL — 权值 -1
  5. THREAD_PRIORITY_LOWEST — 权值 -2
  6. THREAD_PRIORITY_IDEL — 权值设置为 1
  7. THREAD_PRIORITY_TIME_CRITICAL — 权值设置为 15

Windows 的相关 API 为 SetThreadPriority() 和 GetThreadPriority()。如果某一个进程的优先级类别为 HIGH_PRIORITY_CLASS,其中一个线程的优先级等级为 THREAD_PRIORITY_LOWEST 那么它的优先级权值就是 13 – 2 = 11。

上面的两个因素决定了线程的优先权,另外还有一个决定线程优先权的因素:动态提升(Dynamic boost)。
首先,我们可以调整系统的设置,使得 CPU 更加倾向于程序还是后台服务。
除了调整系统设置,键盘消息、鼠标消息、计时器消息都可能引发动态提升,例如,线程获得键盘输入时,就获得了一个 +5 的优先级调整值。
最后,当等待状态得到满足时,例如,Wait… 返回时,此线程的优先权就会获得动态提升。

线程的挂起和执行
// 执行指定的线程
// 函数执行成功返回挂起的次数
// 失败返回 0xFFFFFFFF((DWORD)-1)
DWORD WINAPI ResumeThread(HANDLE hThread);

// 用于挂起指定线程
// 函数执行成功返回先前挂起的次数
// 失败返回 0xFFFFFFFF((DWORD)-1)
DWORD WINAPI SuspendThread(HANDLE hThread);

SuspendThread 最常用的一个用途就是使用在编写调试器上。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值