八宝书库 > 文学其他电子书 > 深入浅出MFC第2版(PDF格式) >

第153部分

深入浅出MFC第2版(PDF格式)-第153部分

小说: 深入浅出MFC第2版(PDF格式) 字数: 每页4000字

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






                                   Good 



                    2 



                                    全域变量X 



                    3                                    1 



                 执行线程B先完成其工作,设定了全域变量X,然后执行线程A才读取X。 



                        ?? 表示执行次序 

                        ?? 



               图  14…6a    race condition (good) 



764 


…………………………………………………………Page 827……………………………………………………………

                                                                        14     MFC  

                                                                     第 章         多緒程式設計 



                           执行线程A                                    执行线程B  

                                               Bad 



                                                                       2 



                                                全域变量X 



                              1                                        3 



                          执行线程A先执行并读取全域变量X,然后执行线程B才设定X。太迟了。 



                                   ?? 表示执行次序 

                                   ?? 



          ????           圖 14…6b    race condition  (bad ) 



NULL                                    执行线程A                              执行线程B 



NULL 



                         执行线程A在此等待 

                                                                                     执行线程B在此等待 

                         全域变量global1 

                                                                                     全域变量global2 

                         从NULL  改变为合                      global 1 

                         法的值                               NULL                      从NULL  改变为合 



                                                                                     法的值 

                                                           NULL 

                         执行线程A在此提供 

                                                                                     执行线程B在此提供 

                                                          global 2 

                         全域变量global2                                                 全域变量global1 



                         的值 

                                                                                     的值 



                                   图14…7 死结 (deadlock) 



                                                                                                 765 


…………………………………………………………Page 828……………………………………………………………

                  第篇    深入  MFC  程式設計 



                  要解决这些问题,必须有办法协调各个执行线程的执行次序,让某个线程等待某个线程。 



                  Windows 系统提供四种同步化机制,帮助程序进行这种工作: 



                    1。 Critical Section (关键区域) 



                    2。 Semaphore  (号志) 



                    3。 Event (事件) 



                    4。 Mutex  (Mutual Exclusive ,互斥器) 



                  MFC 也提供了四个对应的类别: 



                                                  CObject 

                                                   CObject 



                                           CSyncObject 

                                           CSyncObject 



                                              CCriticalSection 

                                               CCriticalSection 



                                                  CEvent 

                                                   CEvent 



                                                  CMutex 

                                                  CMutex 



                                                CSemaphore 

                                                CSemaphore 



                  一想到本书的厚度,我就打消介绍同步机制的念头了。你可以在许多Visual C++ 或MFC 



                  程序设计书籍中得到这个主题的知识。 



             MFC 多线程程序实例 



                  我将在此示范如何把第1章最后的一个Win32 多线程程序MltiThrd 改装为MFC 程序。 



                  我只示范主架构(与CWinThread、AfxBeginThread 、ThreadFunc 有关的部份),程序 



                  绘图部份留给您做练习。 



766 


…………………………………………………………Page 829……………………………………………………………

                                                           14      MFC  

                                                        第 章            多緒程式設計 



首先我利用MFC AppWizard 产生一个Mltithrd 项目,放在书附盘片的Mltithrd。14 子目 



录中,并接受MFC AppWizard  的所有预设选项。 



接下来我在resource。h  中加上一些定义,做为执行线程函数的参数,以便在绘图时能够把 



代表各执行线程的各个长方形涂上不同的颜色: 



 #define HIGHEST_THREAD            0x00 

 #define ABOVE_AVE_THREAD          0x3F 

 #define NORMAL_THREAD             0x7F 

 #define BELOW_AVE_THREAD          0xBF 

 #define LOWEST_THREAD             0xFF 



  然后我在Mltithrd。cpp  中加上一些全域变量(你也可以把它们放在CMltithrdApp 之 



  中。我只是为了图个方便): 



CMltithrdApp theApp; 

CWinThread* _pThread'5'; 

DWORD _ThreadArg'5' = { HIGHEST_THREAD;    // 0x00 

                            ABOVE_AVE_THREAD;  // 0x3F 

                            NORMAL_THREAD;     // 0x7F 

                            BELOW_AVE_THREAD;  // 0xBF 

                            LOWEST_THREAD      // 0xFF 

                          };    //用来调整四方形颜色 



然后在CMltithrdApp::InitInstance  函数最后面加上一些码: 



 // create 5 threads and suspend them 

 int i; 

 for (i= 0; i《 5; i++) 

 { 

                    AfxBeginThread CMltithrdView::ThreadFunc 

    _pThread'i' =                    (                            ; 

                                      &_ThreadArg'i'; 

                                      THREAD_PRIORITY_NORMAL; 

                                      0; 

                                     CREATE SUSPENDED 

                                            _           ; 

                                      NULL); 

 } 



                                                                                          767 


…………………………………………………………Page 830……………………………………………………………

                  第篇    深入  MFC  程式設計 



                  // setup relative priority of threads 

                  _pThread'0'…》SetThreadPriority (THREAD_PRIORITY_HIGHEST); 

                  _pThread'1'…》SetThreadPriority (THREAD_PRIORITY_ABOVE_NORMAL); 

                  _pThread'2'…》SetThreadPriority (THREAD_PRIORITY_NORMAL); 

                  _pThread'3'…》SetThreadPriority (THREAD_PRIORITY_BELOW_NORMAL); 

                  _pThread'4'…》SetThreadPriority (THREAD_PRIORITY_LOWEST); 



                  这样一来我就完成了五个worker threads  的产生,并且将其优先权做了…2~+2 范围之间 



                  的微调。 



                  接下来我应该设计执行线程函数。就如我在第1章已经说过,这个函数的五个执行线程可以 



                  使用同一个执行线程函数。本例中是设计为全域函数好呢?还是static 成员函数好?如果 



                  是后者,应该成为哪一个类别的成员函数好? 



                  为了「要在执行线程函数做窗口绘图动作」的考量,我把执行线程函数设计为CMltithrdView 



                  的一个static 成员函数,并遵循应有的函数类型: 



                  // in MltithrdView。h 

                  class CMltithrdView : public CView 

                  { 

                  。。。 

                  public: 

                          CMltithrdDoc* GetDocument(); 

                          static UINT ThreadFunc(LPVOID); 

                  。。。 

                  }; 



                  // in MltithrdView。cpp 

                  UINT CMltithrdView::ThreadFunc(LPVOID ThreadArg) 

                  { 

                      DWORD dwArg = *(DWORD*)ThreadArg; 



                      // 。。。在这里做如同第1章的MltitThrd 一样的绘图动作 

                      return 0; 

                  } 



                  好,到此为止,编译联结,获得的程序将在执行后产生五个执行线程,并全部冻结。以Process 



                  Viewer (Visual C++ 5。0 所附工具)观察之,证明它的确有六个执行线程(包括一个主执行 



                  线程以及我们所产生的另五个执行线程): 



768 


…………………………………………………………Page 831……………………………………………………………

                                          14      MFC  

                                        第 章        多緒程式設計 



接下来,留给你的操作是: 



  1。 利用资源编辑器为程序加上各菜单项目,如图1…9。 



  2。 设计上述菜单项目的命令处理例程。 



  3。 在执行线程函数ThreadFunc  内加上计算与绘图能力。并判断使用者选择何种延 



  迟方式,做出适当反应。 



                                                                 769 


…………………………………………………………Page 832……………………………………………………………

                第篇    深入  MFC  程式設計 



770 


…………………………………………………………Page 833……………………………………………………………

                                          15           AppWizard 

                                        第 章 定製個 



第15 章 



           定制一个 AppWizard 



 我们的Scribble 程序一路走来,大家可还记得它一开始并不是平地而起,而是由 



 AppWizard  以「程序代码产生器」的身份,自动为我们做出一个我所谓的「骨干程序」来? 



 Developer's Studio 提供了一个开放的AppWizard 接口。现在,我们可以轻易地扩充 



 AppWizard :从小规模的扩充,到几乎改头换面成为一种全新类型的程序代码产生器。 



 Developer's Studio 提供了许多种不同的项目类型,供你选择。当你选按Visual C++ 5。0 整 



 合环境中的【File/New 】命令项,并选择【Projects 】附页,便得到这样的对话窗画面: 



                                                                  771 


…………………………………………………………Page 834……………………………………………………………

                   第篇    深入  MFC 

返回目录 上一页 下一页 回到顶部 0 0

你可能喜欢的