14-15(2)实验指导书(7)

2018-12-03 18:40

static DWORD WINAPI ThreadProc(LPVOID lpParam) {

// 参数中获得this指针并调用对象工作方法

CWorkerThread *pThis= reinterpret_cast(lpParam); pThis->DoStuff(); // 从线程中退出 return(0); }

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 #include

// 封装创建工作线程的类 class CWorkerThread {

public:

CWorkerThread(LPCTSTR SzName):

m_szName(SzName),m_hThread(INVALID_HANDLE_VALUE) {

// 创建新线程并令其启动 m_hThread=CreateThread(

NULL, // 默认的安全性 0, // 默认堆栈

ThreadProc, // 类范围内的线程proc

reinterpret_cast(this), // 发送this指针给proc 0, // 无特殊的创建标志 NULL); // 不需要返回线程ID }

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(lpParam); pThis->DoStuff(); // 从线程中退出 return(0); }

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 #include

// 封装创建工作线程的类 class CWorkerThread {

public:

CWorkerThread(LPCTSTR szName):

m_szName(szName),m_hThread(INVALID_HANDLE_VALUE) {

// 创建新线程并令其启动 m_hThread=CreateThread(

NULL, // 默认的安全性 0, // 默认堆栈

ThreadProc, // 类范围内的线程proc

reinterpret_cast(this), // 发送this指针给proc 0, // 无特殊的创建标志 NULL); // 不需要返回线程ID }

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(lpParam); pThis->DoStuff(); // 从线程中退出 return(0); }

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() {

// 创建两个线程


14-15(2)实验指导书(7).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:银行信贷知识题库(超全)

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: