MFC--线程

来源:互联网 发布:coc法术工厂升级数据 编辑:程序博客网 时间:2024/05/22 12:40
 
模块,进程和线程
 模块一段可执行的程序(包括EXE和DLL),其程序代码,数据,资源被加载到内存中,由系统建置一个数据结构来管理它,就是一个模块.这里所说的数据结构,名为Module Database(MDB),其实就是PE格式中的PE表头,可以从WINNT.H文件中找到一个IMAGE_NT_HEADER结构,就是它.
 
进程就是一大堆拥有权(ownership)的集合.进程拥有地址空间(由memory context决定),动态配置而来的内存,文件,线程和一系列的模块.操作系统使用一个所谓的Process Database (PDB)数据结构,来记录(管理)它所拥有的一切.
 
线程进程主要表达拥有权的观念,线程则主要表达模块中的程序代码的执行事实.系统也是以一个特定的数据结构(Thread Database,TDB)记录线程的所有相关数据,包括线程局部存储空间(Thread Local Storage,TLS),消息队列,handle表格,地址空间(Memory context)等等.
 
Worker threads和UIthreads
从MFC的角度来看,把线程分为和使用者界面无关的worker threads,以及和使用者界面(UI)有关的UIthreads.
基本上,当我们以::CreateThread产生一个线程,并指定一个线程函数,它就是一个worker thread,除非在它的生命中接触到了输入消息这时它应该有一个消息循环,以抓取信息,于是该线程就变为UIthread.
注意,线程本来就带有消息队列.而如果线程代码中带有一个消息循环,就称为UIthread.
worker thread不牵扯使用者界面,应该为它准备一个线程函数,然后调用AfxBeginThread.例如:
CWinThread *pThread = AfxBeginThread(ThreadFunc, &param);
UINT ThreadFunc(LPVOID pParam)
{
}
 UIThread可不能只由一个线程函数来代表,因为它要处理消息.它需要一个消息循环.CWinThread::Run里面就有一个消息循环.所以,我们应该先从CWinThread派生一个自己的类,再调用AfxBeginThread产生CWinThread对象.
 
既然worker thread的生命就是线程函数本身,函数一旦return,线程也就结束,或线程函数也可以调用AfxEndThread,结束一个线程.
UI线程因为有消息循环的关系,比粗在消息队列中放一个WM_QUIT,才能结束线程.放置的方式和一般Win32程序一样,调用::PostQuitMessage即可办到.亦或在线程的任何一个函数中调用AfxEndThread,也可以结束线程.
AfxEndThread其实也是个外封装.其内部调用_endthreadex,这个操作才真正把线程结束掉.
 
原创粉丝点击