哲学家就餐问题——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++ ,