static DWORD WINAPI ThreadProc(LPVOID lpParam) {
// 参数中获得this指针并调用对象工作方法
CWorkerThread *pThis= reinterpret_cast
virtual void DoStuff()
{ // 重复发送线程的ID和名称5次 for(int n=0;n<5;++n) {
printf(\ } }
protected:
HANDLE m_hThread; // 指向线程内核对象的指针 LPCTSTR m_szName; // 显示此线程的名称 };
int main() {
//创建两个线程
CWorkerThread wtA(\ CWorkerThread wtB(\ // 暂停,直到两者都完成为止 wtA.WaitForCompletion(); wtB.WaitForCompletion(); // 报告线程完成
printf(\.\\n\ return 0; }
二、 为线程分配优先权
在应用程序中可为不同的线程指定不同的优先级。为了使系统给予进程的某一部分较多的CPU周期,这是必要的。Windows 2000为进程和线程提供了广泛的优先级授权。优先权可由1~31内的整数来代表,1的优先权最低,31最高。进程优先级表明系统中一个应用程序比另一个应用程序重要的程度,线程优先级表示进程中一个线程比另一个线程重要的程度。Windows按优先级增加的次序,优先级依次为idle(空闲)、lowest(最低)、below-normal(低于正常)、normal(正常)、above-normal(高于正常)、highest(最高)和time-critical(与时间相关的)。
在创建线程后,就可以改变其优先级了。改变优先级可在实际开始执行之前进行,可将该线程创建为挂起的,改变其优先级,然后调用ResumeThread()API函数。
1.相关API函数说明 (1)GetCurrentThreadId
函数功能:该函数可获得当前线程的id。对线程而言,该值是惟一的,可以在全系统运行。
函数格式:
DWORD GetCurrentThreadId(void)。 参数:无。
返回值:若函数调用成功则返回当前线程的标志符,否则返回NULL。 (2)SetThreadPriority
函数功能:该函数用来设置线程优先级。 函数格式:
BOOL SetThreadPriority( HANDLE hTread,int nPriority); 参数:hTread线程句柄;nPriority指定线程的优先级。 返回值:若函数调用成功,返回非零值,否则返回值为0。 2.改变线程优先级的实例程序
为了掌握SetPriority()API函数的使用方法,下面举例来说明。 例3-2 :改变线程的优先级。 #include
// 封装创建工作线程的类 class CWorkerThread {
public:
CWorkerThread(LPCTSTR SzName):
m_szName(SzName),m_hThread(INVALID_HANDLE_VALUE) {
// 创建新线程并令其启动 m_hThread=CreateThread(
NULL, // 默认的安全性 0, // 默认堆栈
ThreadProc, // 类范围内的线程proc
reinterpret_cast
virtual ~CWorkerThread() {
CloseHandle(m_hThread); }
// 等待线程完成的方法
virtual void WaitForCompletion() {
WaitForSingleObject(m_hThread,INFINITE); }
// 改变线程的优先级
virtual void SetPriority(int nPriority)
{
SetThreadPriority(m_hThread,nPriority); }
protected:
static DWORD WINAPI ThreadProc(LPVOID lpParam) {
// 从参数lpParam中获得this指针并调用线程对象工作方法 CWorkerThread*pThis=
reinterpret_cast
virtual void DoStuff() {
// 重复8次地发送线程的ID和名称 for(int n=1; n<=8; ++n) {
printf(\:%d,count %d\\n\ GetCurrentThreadId(),n); } }
protected:
HANDLE m_hThread; //指向线程内核对象的指针 LPCTSTR m_szName;//显示此线程的名称 };
int main() {
// 创建两个线程
CWorkerThread wtA(\ CWorkerThread wtB(\ // 使线程A的优先级尽可能低
wtA.SetPriority(THREAD_PRIORITY_LOWEST); wtB.SetPriority(THREAD_PRIORITY_NORMAL); // 暂停,直到两者都完成为止 wtA.WaitForCompletion(); wtB.WaitForCompletion(); // 报告线程完成
printf(\.\\n\}
三、 挂起和激活线程
前面的例1展示了通过创建两个线程之后,主线程调用WaitForCompletion()API等待
两个线程完成,并将线程从准备运行的线程队列中移人到挂起队列中。一旦目标满足了等待函数的条件(线程完成),内核就将该线程再移回准备运行队列中。对现有线程可以执行的另一个操作是人工暂停和恢复它们,也可用程序响应的方式进行这些操作。下面借用一个例子来展示如何使用SuspendThread()和ResumeThread()API函数,将线程挂起,然后再恢复为运行状态。
1.相关API函数说明 (1)ResumeThread
函数功能:该函数重新激活被挂起的线程,系统会为每个线程建立一个挂起计数。调用一次该函数,使挂起计数减1,只要挂起计数恢复为0时,就恢复这个挂起线程的运行。
函数格式:
DWORD ResumeThread(HANDLE hTread);
参数:hTread指定待挂起的线程对象的句柄。
返回值:若函数调用成功,返回该线程先前的挂起记数,否则返回OxFFFFFFFF。 (2)SuspendThread
函数功能:该函数用于挂起一个线程,系统会为每个线程建立一个挂起计数。调用一次该函数,使挂起计数加1,只要挂起计数大于0,则挂起该线程。
函数格式:
DWORD SuspendThread(HANDLE hTread);
参数:hTread指定待挂起的线程对象的句柄。
返回值:若函数调用成功,返回该线程先前的挂起记数,否则返回OxFFFFFFFF。 2.线程暂停与恢复的实例程序 例3-3: 线程的暂停与恢复。 #include
// 封装创建工作线程的类 class CWorkerThread {
public:
CWorkerThread(LPCTSTR szName):
m_szName(szName),m_hThread(INVALID_HANDLE_VALUE) {
// 创建新线程并令其启动 m_hThread=CreateThread(
NULL, // 默认的安全性 0, // 默认堆栈
ThreadProc, // 类范围内的线程proc
reinterpret_cast
virtual ~CWorkerThread() {
CloseHandle(m_hThread); }
// 等待线程完成的方法
virtual void WaitForCompletion() {
WaitForSingleObject(m_hThread,INFINITE); }
// 改变线程的优先级
virtual void SetPriority(int nPriority) {
SetThreadPriority(m_hThread,nPriority); }
// 线程挂起
virtual void Suspend() {
SuspendThread(m_hThread); }
// 线程恢复
virtual void Resume() {
ResumeThread(m_hThread); }
protected:
static DWORD WINAPI ThreadProc(LPVOID lpParam) {
// 从参数中获得this指针并调用对象的工作方法
CWorkerThread*pThis= reinterpret_cast
virtual void DoStuff() {
// 重复8次发送线程的ID和名称 for(int n=1; n<8; ++n) {
printf(\:%d,count %d\\n\ GetCurrentThreadId(),n); } }
protected:
HANDLE m_hThread; //指向线程内核对象的指针 LPCTSTR m_szName; //显示此线程的名称 };
int main() {
// 创建两个线程