友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
一世书城 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

深入浅出MFC第2版(PDF格式)-第184章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!






                   SerializeRaw  函数即可。 



                   为了这NewDoc 文件类型能够读写文件,我们也依样画葫芦地把上一段码阴影部份加到 



                   Graph 程序新的Document 类别去: 



                    void CNewDoc::Serialize(CArchive& ar) 

                    { 

                            if (ar。IsStoring()) 

                            { 

                                    // TODO: add storing code here 

                            } 

                            else 

                            { 

                                    // TODO: add loading code here 

                            } 



                            // CEditView contains an edit control which handles all serialization 

                            ((CEditView*)m_viewList。GetHead())…》SerializeRaw(ar); 

                    } 



742 


…………………………………………………………Page 805……………………………………………………………

                                         第 13 章    多重文件與多重顯示 



现在一切完备,重新编辑联结并执行。一开始,由于InitInstance  函数会自动为我们New 



一个新文件,而Graph 程序不知道该New  哪一种文件类型才好,所以会给我们这样的 



对话框: 



往后每一次选按【File/New 】,都会出现上述对话框。 



以下是我们打开Graph 文件和NewDoc 文件各一份的画面。注意,当active 窗口是 



NewDoc 文件,工具栏上属于Graph 文件所用的最后三个按钮是不起作用的: 



                                                                 743 


…………………………………………………………Page 806……………………………………………………………

                第篇    深入  MFC  程式設計 



                以下是【Open 】对话框(用来开档)。注意,文件有。fig 和。txt 和*。* 三种选择: 



                这个新的Graph 版本放在书附光盘片的GRAPH2。13  目录中。 



744 


…………………………………………………………Page 807……………………………………………………………

                                            14     MFC  

                                          第 章       多緒程式設計 



        14 

      第  章 



                MFC  多线程程序设计 

          Multi…threaded Programming in MFC 



     线程(thread ),是执行线程(thread of execution )的简单称呼。〃Thread〃 这个字的原意是「线」。 



      中文字里头的「线程」也有「线」的意思,所以我采用「线程」、「执行线程」这样的中文名 



     称。如果你曾经看过「多线」这个名词,其实就是本章所谓的「多线程」。 



     我曾经在第1章以三两个小节介绍Win32 环境下的进程与执行线程观念,并且以程序直接 



     调用CreateThread 的形式,示范了几个Win32 小例子。现在我要更进一步从操作系统 



      的层面谈谈执行线程的学理基础,然后带引各位看看MFC 对于「执行线程」支持了什么样 



      的类别。然后,实际写个MFC 多线程程序。 



从操作系统层面看执行线程 



     书籍推荐:如果要从操作系统层面来了解执行线程,Matt Pietrek  的Windows 95 System 



     Programming SECRETS  (Windows 95 系统程序设计大奥秘/侯俊杰译/旗标出版)无疑是 



     最佳知识来源。Matt 把操作系统核心模块(KERNEL32。DLL )中用来维护执行线程生存的 



     数据结构都挖掘出来,非常详尽。这是对执行线程的最基础认识,直达其灵魂深处。 



                                                                745 


…………………………………………………………Page 808……………………………………………………………

             第篇    深入  MFC  程式設計 



             你已经知道,CreateThread 可以产生一个执行线程,而「线程」的本体就是CreateThread 第 



             3个参数所指定的一个函数(一般我们称之为「执行线程函数」)。这个函数将与目前的 



             「执行事实」同时并行,成为另一个「执行事实」。执行线程函数的执行期,也就是该执 



             行线程的生命期。 



             操作系统如何造成这种多任务并行的现象?执行线程对于操作系统的意义到底是什么?系统 



             如何维护许多个执行线程?执行线程与其父亲大人(进程)的关系如何维持?CPU 只有一 



             个,执行线程却有好几个,如何摆平优先权与排程问题?这些疑问都可以在下面各节中获 



             得答案。 



        三个观念:模块、进程、执行线程 



             试着回答这个问题:进程(process )是什么?给你一分钟时间。 



             z z z z z。。。 



             你的回答可能是:『一个可执行档执行起来,就是一个进程』。唔,也不能算错。但能 



             不能够有更具体的答案?再问你一个问题:模块(module )是什么?可能你的回答还是: 



             『一个可执行档执行起来,就是一个模块』。这也不能够算错。但是你明明知道,模块 



             不等于进程。KERNEL32 DLL 是一个模块,但不是一个进程;Scribble EXE 是一个模块, 



             也是一个进程。 



             我们需要更具体的资料,更精准的答案。 



             如果我们能够知道操作系统如何看待模块和进程,就能够给出具体的答案了。一段可执 



             行的程序(包括EXE 和DLL ),其程序代码、资料、资源被加载到内存中,由系统建 



             置一个数据结构来管理它,就是一个模块。这里所说的数据结构,名为Module Database 



             (MDB ),其实就是PE 格式中的PE 表头,你可以从WINNT。H 档中找到一个 



             IMAGE_NT_HEADER  结构,就是它。 



746 


…………………………………………………………Page 809……………………………………………………………

                                           14     MFC  

                                         第 章        多緒程式設計 



好,解释了模块,那么进程是什么?这就比较抽象一点了。这样说,进程就是一大堆拥 



有权(ownership )的集合。进程拥有地址空间(由memory context 决定)、动态配置而 



来的内存、文件、执行线程、一系列的模块。操作系统使用一个所谓的Process Database 



 (PDB )数据结构,来记录(管理)它所拥有的一切。 



执行线程呢?执行线程是什么?进程主要表达「拥有权」的观念,执行线程则主要表达模块中 



的程序代码的「执行事实」。系统也是以一个特定的数据结构(Thread Database,TDB )记 



录执行线程的所有相关资料,包括执行线程区域储存空间(Thread Local Storage ,TLS )、讯 



息队列、handle 表格、地址空间(Memory Context )等等等。 



最初,进程是以一个执行线程(称为主执行线程,primary thread )做为开始。如果需要,行 



程可以产生更多的执行线程(利用CreateThread),让CPU 在同一时间执行不同段落的 



码。当然,我们都知道,在只有一颗CPU  的情况下,不可能真正有多任务的情况发生, 



 「多个执行线程同时工作」的幻觉主要是靠排程器来完成…它以一个硬件定时器和一组复 



杂的游戏规则,在不同的执行线程之间做快速切换动作。以Windows 95 和Windows NT 



而言,在非特殊的情况下,每个执行线程被CPU 照顾的时间(所谓的timeslice )是20 个 



milliseconds 。 



如果你有一部多CPU 计算机,又使用一套支持多CPU  的操作系统(如Windows NT ), 



那么一个CPU 就可以分配到一个执行线程,真正做到实实在在的多任务。这种操作系统特性 



称为symmetric multiprocessing  (SMP)。Windows 95 没有SMP 性质,所以即使在多CPU 



计算机上跑,也无法发挥其应有的高效能。 



图14…1 表现出一个进程(PDB )如何透过「MODREF  串行」连接到其所使用的所有模 



组。图14…2 表现出一个模块数据结构(MDB )的细部内容,最后的DataDirectory'16' 记 



录着16 个特定节区(sections )的地址,这些sections 包括程序代码、资料、资源。图 



14…3 表现出一个执行线程数据结构(PDB )的细部内容。 



                                                                  747 


…………………………………………………………Page 810……………………………………………………………

                        第篇    深入  MFC  程式設計 



                        当Windows 加载器将程序加载内存中,KERNEL32 挖出一些内存,构造出一个 



                        PDB 、一个TDB 、一个以上的MDBs                     (视此程序使用到多少DLL 而定)。针对TDB , 



                        操作系统又要产生出memory context                  (就是在操作系统书籍中提到的那些所谓page 



                        tables )、消息队列、handle 表格、环境数据结构(EDB )。。。。当这些系统内部数据结构 



                        都构造完毕,指令指位器(Instruction Pointer )移到程序的进入点,才开始程序的执行。 



                                                                                         Module Table               IMTEs 



                                                              pModuleTableArray                0               KERNEL32。DLL 

                          Process 

                         Database                                                    )          1  
返回目录 上一页 下一页 回到顶部 0 1
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!