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

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

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




                   #0016      fFibo。Open (〃FIBO。DAT〃; CFile::modeWrite | 

                   #0017                  CFile::modeCreate | CFile::typeText); 

                   #0018 

                   #0019      str。Format (〃%sn〃; 〃Fibonacci sequencee; less than 100 :〃); 

                   #0020      printf(〃%s〃; (LPCTSTR) str); 

                   #0021      fFibo。WriteString (str); 

                   #0022 

                   #0023      lo = hi = 1; 

                   #0024 

                   #0025      str。Format (〃%dn〃; lo); 

                   #0026      printf(〃%s〃; (LPCTSTR) str); 

                   #0027      fFibo。WriteString (str); 

                   #0028 

                   #0029      while (hi 《 100) 

                   #0030      { 

                   #0031          str。Format (〃%dn〃; hi); 

                   #0032          printf(〃%s〃; (LPCTSTR) str); 

                   #0033          fFibo。WriteString (str); 

                   #0034          hi = lo + hi; 

                   #0035          lo = hi lo; 

                   #0036      } 

                   #0037 

                   #0038      fFibo。Close (); 

                   #0039      return 0; 

                   #0040  } 



                   以下是执行结果(在  console  窗口和  FIBO。DAT 档案中,结果都一样): 



36 


…………………………………………………………Page 99……………………………………………………………

Fibonacci sequencee; less than 100  : 



1 1 2 3 5 8 



13 



21 



34 



55 



89 



这么简单的例子中,我们看到MFC Console 程序的几个重点: 



1。 程序进入点仍为main 



2。 需包含所使用之类别的头文件(本例为AFX。H ) 



3。 可直接使用与GUI 无关的MFC 类别(本例为CStdioFile 和CString ) 



4。 编辑时需指定/MT,表示使用多执行线程版本的C runtime  函数库。 



第4点需要多做说明。在MFC console 程序中一定要指定多线程版的C runtime  函数库, 



所以必须使用/MT 选项。如果不做这项设定,会出现这样的联结错误: 



Microsoft  (R) 32…Bit Incremental Linker Version 5。00。7022 



Copyright  (C) Microsoft Corp 1992…1997。 All rights reserved。 



/out:mfccon。exe 



mfccon。obj 



nafxcw。lib (thrdcore。obj)  : error LNK2001: unresolved external symbol __endthreadex 



nafxcw。lib (thrdcore。obj)  : error LNK2001: unresolved external symbol __beginthreadex 



mfccon。exe  : fatal error LNK1120: 2 unresolved externals 



表示它找不到__beginthreadex 和__endthreadex 。怪了,我们的程序有调用它们吗?没 



有,但是MFC 有!这两个函数将在稍后与执行线程有关的小节中讨论。 



MFCCON  的源代码与可执行文件放在书附盘片的mfccon。01 子目录中。 



                                                                                     37 


…………………………………………………………Page 100……………………………………………………………

                什么是C Runtime 函数库的多线程版本 



当C runtime  函数库于1970s 年代产生出来时,PC 的内存容量还很小,多任务是 



个新奇观念,更别提什么多执行线程了。因此以当时产品为基础所演化的C runtime  函 



数库在多线程(multithreaded)的表现上有严重问题,无法被多线程程序使用。 



利用各种同步机制(                          )如             、     、         、 

                 synchronous mechanism critical section mutex semaphore 



    ,可以重新开发一套支持多执行线程的                     函数库。问题是,加上这样的能 

event                              runtime  



力,可能导至程序代码大小和执行效率都遭受不良波及  即使你只激活了一个执行 

                                            … 



线程。 



Visual C++  的折衷方案是提供两种版本的C runtime  函数库。一种版本给单线程程序 



使用,一种版本给多线程程序使用。多线程版本的重大改变是,第一,变量如errno 者 



现在变成每个执行线程各拥有一个。第二,多线程版中的数据结构以同步机制加以保护。 



Visual C++ 一共有六个C runtime  函数库产品供你选择: 



  ◆              (    )  

    Single…Threaded static libc。lib 898;826 

      



               (    )  

    Multithreaded static libcmt。lib 951;142 

      

  ◆ 



    Multithreaded DLL msvcrt。lib 5;510;000 

      

  ◆ 



                       (    )  

    Debug Single…Threaded static libcd。lib 2;374;542 

      

  ◆ 



                     (    ) 

    Debug Multithreaded static libcmtd。lib 2;949;190 

      

 ◆ 



 ◆ Debug Multithreaded DLL msvcrtd。lib 803;418 

      



Visual C++ 编译器提供下列选项,让我们决定使用哪一个C runtime  函数库: 



 ◆                   (    ) 

    /ML Single…Threaded static 

      



 ◆                 (    ) 

    /MT Multithreaded static 

      



                        (                 ) 

    /MD Multithreaded DLL dynamic import library 

 ◆   



                            (   ) 

    /MLd Debug Single…Threaded static 

 ◆   



                          (    ) 

    /MTd Debug Multithreaded static 

 ◆   



 ◆                            (                 ) 

    /MDd Debug Multithreaded DLL dynamic import library 

      



                                                                             38 


…………………………………………………………Page 101……………………………………………………………

进程与执行线程 (                                             ) 

                         Process and Thread 



    OS/2 Windows NT    Windows 95                     PC  

        、           以及           都支持多执行线程,这带给           程序员一股令人兴 



    奋的气氛。然而它带来的不全然是利多,如果不谨慎小心地处理执行线程的同步问题,程 



    序的错误以及除错所花的时间可能使你发誓再也不碰「执行线程」这种东西。 



    我们习惯以进程(process )表示一个执行中的程序,并且以为它是CPU 排程单位。事 



    实上执行线程才是排程单位。 



  核心对象 



    首先让我解释什么叫作「核心对象」(kernel object )。「GDI 对象」是大家比较熟悉的 



                GDI                   Pen          Brush            GDI 

    东西,我们利用         函数所产生的一支笔(           )或一支刷(         )都是所谓的「 



    对象」。但什么又是「核心对象」呢? 



    你可以说核心对象是系统的一种资源(噢,这说法对GDI 对象也适用),系统对象一 



    旦产生,任何应用程序都可以开启并使用该对象。系统给予核心对象一个计数值(usage 



    count )做为管理之用。核心对象包括下列数种: 



          核心对象               产生方法 



         event                 CreateEvent 



         mutex                 CreateMutex 



         semaphore             CreateSemaphore 



         file                  CreateFile 



         file…mapping          CreateFileMapping 



         process               CreateProcess 



         thread                CreateThread 



    前三者用于执行线程的同步化:file…mapping 对象用于内存映射文件(memory mapping 



    file  process  thread  

       ),       和     对象则是本节的主角。这些核心对象的产生方式(也就是我们 



                                                                              39 


…………………………………………………………Page 102……………………………………………………………

           API                   handle  

    所使用的      )不同,但都会获得一个             做为识别;每被使用一次,其对应的计 



           1                              CloseHandle  

    数值就加 。核心对象的结束方式相当一致,调用                          即可。 



      process  

     「     对象」究竟做什么用呢?它并不如你想象中用来「执进程序代码」;不,程序代码 



    的执行是执行线程的工作,「process 对象」只是一个数据结构,系统用它来管理进程。 



一个进程的诞生与死亡 



    执行一个程序,必然就产生一个进程(process )。最直接的程序执行方式就是在shell                      (如 



    Win95  的文件总管或Windows 3。x  的文件管理员)中以鼠标双击某一个可执行文件图标 



             App。exe           App         shell   CreateProcess  

     (假设其为         ),执行起来的         进程其实是       调用             激活的。 



    让我们看看整个流程: 



    1。 shell 调用CreateProcess 激活App。exe 。 



                                        1 

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