Windows多线程多任务设计初步学习

 

   一、 理解线程

  要讲解线程,不得不说一下进程,进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它系统资源组成。进程在运行时创建的资源随着进程的终止而死亡。 线程的基本思想很简单,它是一个独立的执行流,是进程内部的一个独立的执行单元,相当于一个子程序,它对应 Visual C++ 中的 CwinThread 类的对象。 单独一个执行程序运行时,缺省的运行包含的一个主线程,主线程以函数地址的形式,如 main WinMain 函数,提供程序的启动点,当主线程终止时,进程也随之终止,但根据需要,应用程序又可以分解成许多独立执行的线程,每个线程并行的运行在同一进程中。

  一个进程中的所有线程都在该进程的虚拟地址空间中,使用该进程的全局变量和系统资源。操作系统给每个线程分配不同的 CPU 时间片,在某一个时刻, CPU 只执行一个时间片内的线程,多个时间片中的相应线程在 CPU 内轮流执行,由于每个时间片时间很短,所以对用户来说,仿佛各个线程在计算机中是并行处理的。操作系统是根据线程的优先级来安排 CPU 的时间,优先级高的线程优先运行,优先级低的线程则继续等待。

  线程被分为两种: 用户界面线程和工作线程(又称为后台线程) 。用户界面线程通常用来处理用户的输入并响应各种事件和消息,其实,应用程序的主执行线程 CWinAPP 对象就是一个用户界面线程,当应用程序启动时自动创建和启动,同样它的终止也意味着该程序的结束,进城终止。工作者线程用来执行程序的后台处理任务,比如计算、调度、对串口的读写操作等,它和用户界面线程的区别是它不用从 CwinThread 类派生来创建,对它来说最重要的是如何实 现工作线程任务的运行控制函数 。工作线程和用户界面线程启动时要调用同一个函数的不同版本;最后需要读者明白的是,一个进程中的所有线程共享它们父进程的变量,但同时每个线程可以拥有自己的变量。
二、 线程的管理和操作

   1 线程的启动

  创建一个用户界面线程,首先要从类 CwinThread 产生一个派生类,同时必须使用 DECLARE_DYNCREATE IMPLEMENT_DYNCREATE 来声明和实现这个 CwinThread 派生类。

  第二步是根据需要重载该派生类的一些成员函数如: ExitInstance() InitInstance() OnIdle();PreTranslateMessage() 等函数,最后启动该用户界面线程,调用 AfxBeginThread() 函数的一个版本: CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ); 其中第一个参数为指向定义的用户界面线程类指针变量,第二个参数为线程的优先级,第三个参数为线程所对应的堆栈大小,第四个参数为线程创建时的附加标志,缺省为正常状态,如为 CREATE_SUSPENDED 则线程启动后为挂起状态。

  对于工作线程来说,启动一个线程,首先需要编写一个希望与应用程序的其余部分并行运行的函数如 Fun1() ,接着定义一个指向 CwinThread 对象的指针变量 *pThread, 调用 AfxBeginThread(Fun1,param,priority) 函数,返回值付给 pThread 变量的同时一并启动该线程来执行上面的 Fun1() 函数,其中 Fun1 是线程要运行的函数的名字,也既是上面所说的控制函数的名字, param 是准备传送给线程函数 Fun1 的任意 32 位值, priority 则是定义该线程的优先级别,它是预定义的常数,读者可参考 MSDN

   2 .线程的优先级

  以下的 CwinThread 类的成员函数用于线程优先级的操作:

int GetThreadPriority();
BOOL SetThradPriority()(int nPriority);


上述的二个函数分别用来获取和设置线程的优先级,这里的优先级,是相对于该线程所处的优先权层次而言的,处于同一优先权层次的线程,优先级高的线程先运行;处于不同优先权层次上的线程,谁的优先权层次高,谁先运行。至于优先级设置所需的常数,自己参考 MSDN 就可以了,要注意的是要想设置线程的优先级,这个线程在创建时必须具有 THREAD_SET_INFORMATION 访问权限。对于线程的优先权层次的设置, CwinThread 类没有提供相应的函数,但是可以通过 Win32 SDK 函数 GetPriorityClass() SetPriorityClass() 来实现。

   3 .线程的悬挂、恢复

   CwinThread 类中包含了应用程序悬挂和恢复它所创建的线程的函数,其中 SuspendThread() 用来悬挂线程,暂停线程的执行; ResumeThread() 用来恢复线程的执行。如果你对一个线程连续若干次执行 SuspendThread() ,则需要连续执行相应次的 ResumeThread() 来恢复线程的运行。

   4 .结束线程

  终止线程有三种途径,线程可以在自身内部调用 AfxEndThread() 来终止自身的运行;可以在线程的外部调用 BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode ) 来强行终止一个线程的运行,然后调用 CloseHandle ()函数释放线程所占用的堆栈;第三种方法是改变全局变量,使线程的执行函数返回,则该线程终止。下面以第三种方法为例,给出部分代码:


//CtestView message handlers
/Set to True to end thread
Bool bend=FALSE;//
定义的全局变量,用于控制线程的运行
//The Thread Function
UINT ThreadFunction(LPVOID pParam)//线程函数
{
while(!bend)
{Beep(100,100);
Sleep(1000);
}
return 0;
}
CwinThread *pThread;
HWND hWnd;
/
Void CtestView::OninitialUpdate()
{
hWnd=GetSafeHwnd();
pThread=AfxBeginThread(ThradFunction,hWnd);//启动线程
pThread->m_bAutoDelete=FALSE;//线程为手动删除
Cview::OnInitialUpdate();
}

Void CtestView::OnDestroy()
{ bend=TRUE;//改变变量,线程结束
WaitForSingleObject(pThread->m_hThread,INFINITE);//等待线程结束
delete pThread;//删除线程
Cview::OnDestroy();
}

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值