当前位置:编程学习 > C/C++ >>

哲学家就餐问题——MFC演示程序

[cpp]
</pre><pre name="code" class="cpp"> 
     这个问题实际上就是多线程的调度问题,因为MFC里面已经给我们封装好了线程类,CWinThread类,因此我们要做的仅仅是简单的为每位哲学家分别创建进程。程序逻辑不是很复杂,但在用MFC来做哲学家就餐问题的演示问题时,就涉及到的图像绘制可能比较麻烦,因为你要给每位哲学家的当前状态给出相应的图示。

\

这个是我写的演示程序的主界面,左边使用图形显示哲学家就餐中的一些状态切换,右边用编辑框给每位哲学家配以文字说明。

     一、先说下演示程序的核心部分,CWinThread类和CCriticalSection临界区类

            MFC给我们封装好了线程类CWinThread供我们在程序里面去创建新的线程,其提供了两种线程,工作线程和用户线程(具体区别可以去查相应资料,这里就不多说了),本程序采用的是工作线程(工作线程就是在后台处理大量数据,并不需要响应消息请求,用户线程就是在线程运行的时候还要时刻捕获用户的消息请求)。

           工作线程创建很简单

           CWinThread *pThread;

            pThread->AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );

           函数具体参数可以查MSDN,我们常用的就是前面两个参数,第一个是是指定我们创建的线程所执行的代码,第二个参数是我们要传递给线程的数据结构。

           本程序因为有六位哲学家,所以我创建了6个线程,并为其指定了执行函数        


[cpp] CWinThread *pthread[6]; 
       for(int i=0;i<6;i++) 
           pthread[i]=AfxBeginThread(Eat,&imageinfo[i]); 
 CWinThread *pthread[6];
        for(int i=0;i<6;i++)
            pthread[i]=AfxBeginThread(Eat,&imageinfo[i]);
          其中Eat是我指定线程执行的代码,因为本演示程序中六位哲学家做的事都是一样的,所以每位哲学家线程的执行代码也是一样的,imageinfo是我要从主程序中传递给线程的一些基本数据信息。         

 

[cpp] struct ImageInfo 

  int index;                                   //索引,表示当前的是几号哲学家线程在执行  
  CPoint pt_chair;                         //椅子的坐标  
  CPoint pt_chopstick_middle[2]; //  
  CPoint pt_chopstick_start[2];     //叉子的坐标信息  
  CPoint pt_chopstick_end[2];      //  
  double radius_chair;                 //椅子半径  
  double radius_table;                 //桌子的半径  
  CWnd* pWnd;                          //主程序窗口的句柄  
  CRect rect;    
  HWND edit;                             //右边相应编辑框的句柄  
}; 
struct ImageInfo
{
  int index;                                   //索引,表示当前的是几号哲学家线程在执行
  CPoint pt_chair;                         //椅子的坐标
  CPoint pt_chopstick_middle[2]; //
  CPoint pt_chopstick_start[2];     //叉子的坐标信息
  CPoint pt_chopstick_end[2];      //
  double radius_chair;                 //椅子半径
  double radius_table;                 //桌子的半径
  CWnd* pWnd;                          //主程序窗口的句柄
  CRect rect;  
  HWND edit;                             //右边相应编辑框的句柄
};        [cpp] UINT Eat(LPVOID param) 
{    
    while (true)                     //设置为无线循环,好让线程一直运行下去  
    { 
 
    ImageInfo *imageinfo=(ImageInfo*)param; 
    CDC *pDC=imageinfo->pWnd->GetDC();               //获得主程序窗口的DC  
       //char textbuff[1024];  
    //::GetWindowText(imageinfo->edit,textbuff,1024);  
    CString text; 
    CString temp; 
    bool caneat=FALSE;                                              //标识变量,验证当前哲学家线程是否可以就餐 
UINT Eat(LPVOID param)
{  
 while (true)                     //设置为无线循环,好让线程一直运行下去
 {

 ImageInfo *imageinfo=(ImageInfo*)param;
 CDC *pDC=imageinfo->pWnd->GetDC();               //获得主程序窗口的DC
       //char textbuff[1024];
 //::GetWindowText(imageinfo->edit,textbuff,1024);
 CString text;
 CString temp;
 bool caneat=FALSE;                                              //标识变量,验证当前哲学家线程是否可以就餐[cpp] CBrush brush_think,brush_eat,brush_wait,*oldbrush;  //表示各种状

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,