⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dining.c

📁 计算机操作系统中解决哲学家吃饭的问题的VC++实现。
💻 C
字号:
/*
 * Dining.c
 *
 * Sample code for "Multithreading Applications in Win32"
 * This sample is discussed in Chapter 4.
 *
 * Graphically demonstrates the problem of the
 * dining philosophers.
 */

#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <windowsx.h>
#include <string.h>
#include <math.h>
#include "dining.h"

HINSTANCE 	hInst;			// Application Instance Handle
HWND   	hWndMain;       	// Main Window Handle                             
HBITMAP	hbmpOffscreen;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void RenderOffscreen(HDC hDestDC);
char *psText;
BOOL bWaitMultiple;
BOOL bFastFood;
int iLength;
int state=0;
extern int gDinerState[];
extern int gChopstickState[];
extern HANDLE gchopStick[PHILOSOPHERS];	// 1 chopstick between each philopher and his neighbor

/********************************************************************/
/*	ROUTINE:	WndProc												*/
/*																	*/
/*	PURPOSE:	Processes messages									*/
/********************************************************************/

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
	WPARAM wParam, LPARAM lParam)	
{
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message) 
	{
		case WM_COMMAND:		
			switch (wParam) 
			{
			case CM_EXIT:
				PostMessage(hWndMain, WM_CLOSE, 0, 0L);
				break;  
			} 
			break;

		case WM_FORCE_REPAINT:
			{
				MSG msg;

				InvalidateRect(hWndMain, NULL, TRUE);//产生WM_PAINT函数
				while (PeekMessage(&msg, hWndMain, WM_FORCE_REPAINT,WM_FORCE_REPAINT,TRUE));
			}
			break;

		case WM_PAINT:
			
			hdc = BeginPaint(hWndMain, &ps);

			RenderOffscreen(hdc);
			
			EndPaint(hWndMain, &ps);
			break;

		case WM_CLOSE:
			return DefWindowProc(hWndMain, message, wParam, lParam);

		case WM_DESTROY:
			PostQuitMessage(0);
			break;

		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
}
	return (0);
}

BOOL CreateOffscreen()
{
	HWND hwndScreen = GetDesktopWindow();
	HDC hdc	= GetDC(hwndScreen);

	int	nWidth	= GetSystemMetrics( SM_CXSCREEN );
	int	nHeight	= GetSystemMetrics( SM_CYSCREEN );

	hbmpOffscreen = CreateCompatibleBitmap( hdc, nWidth, nHeight );

	ReleaseDC(hwndScreen, hdc);

	if ( !hbmpOffscreen )
		return FALSE;
	else
		return TRUE;
}

void RenderOffscreen(HDC hDestDC)
{
	HDC hdc				= hDestDC; // CreateCompatibleDC(hWndMain);
	int err=GetLastError();
	HBITMAP hOldBitmap	= SelectObject(hdc, hbmpOffscreen);
	RECT rect;
	HPEN hPen;
	double dx, dy, px, py,  AngRad, dDeltaAng;
	int pos, p1;
	long CenterX, CenterY;

	hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, 0L));

	GetClientRect(hWndMain, &rect);

	/* Draw the table */
	CenterX = (rect.right - rect.left)/2;
	CenterY = (rect.bottom - rect.top)/2;
	Ellipse(hdc, CenterX - 100, CenterY - 100, CenterX + 100, CenterY + 100);

	/* Draw the chopsticks */
	dDeltaAng = 360 / PHILOSOPHERS;    //筷子间的角度差
	for (pos = 0; pos < PHILOSOPHERS; pos++)	//FIXIT
	{
		/* Draw the chopsticks */
		AngRad = (pos * dDeltaAng)/57.29577951;  //转化为弧度
		dx = CenterX + (sin(AngRad)*60);
		dy = CenterY - (cos(AngRad)*60);
		MoveToEx(hdc, (int)dx, (int)dy, NULL);
		dx = CenterX + (sin(AngRad)*85);
		dy = CenterY - (cos(AngRad)*85);
		LineTo(hdc, (int)dx, (int)dy);

		//Draw the plate
		AngRad = ((pos * dDeltaAng+dDeltaAng / 2))/57.29577951;  //转化为弧度
		dx = CenterX + (sin(AngRad) * 72);
		dy = CenterY - (cos(AngRad) * 72);
		Ellipse(hdc, (int)dx-12, (int)dy-12, (int)dx+12, (int)dy+12);
	}

	/* delete the black pen */
	DeleteObject(SelectObject(hdc, hPen));

	/* Draw the philosophers */
	for(pos = 0; pos < PHILOSOPHERS; pos++)
	{
		/* select a pen for each philosopher */
		switch (gDinerState[pos])
		{
			//此处可以改变显示画面状态
		case RESTING:
			hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(0, 255, 0)));
			psText="休息休息!";
			iLength=9;
			state=0;
			break;

		case WAITING:
			hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(255, 0, 0)));
			psText="我要筷子...";
			iLength=11;
			state=1;
			break;
		case EATING:
			hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(255, 0, 0)));
			psText="好香啊!";
			iLength=7;
			state=2;
			break;

		default:
			hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, 0L));
		}

		AngRad = ((pos * dDeltaAng) + dDeltaAng / 2)/57.29577951;
		px = CenterX + (sin(AngRad)*180);
		py = CenterY - (cos(AngRad)*180);

		/* Draw the Philosopher */
		Ellipse(hdc, (int)px-25, (int)py-25, (int)px+25, (int)py+25);

		TextOut (hdc, (int)px-30, (int)py-42,psText, iLength) ;
		if(state==0)
		{
			MoveToEx(hdc, (int)px-15, (int)py-10, NULL);
			LineTo(hdc, (int)px-5, (int)py-10);
			MoveToEx(hdc, (int)px+5, (int)py-10, NULL);
			LineTo(hdc, (int)px+15, (int)py-10);
			MoveToEx(hdc, (int)px-5, (int)py+10, NULL);
			LineTo(hdc, (int)px+5, (int)py+10);
		}
		else if(state==1)
		{
			MoveToEx(hdc, (int)px-15, (int)py-10, NULL);
			LineTo(hdc, (int)px-5, (int)py-10);
			MoveToEx(hdc, (int)px+5, (int)py-10, NULL);
			LineTo(hdc, (int)px+15, (int)py-10);
			Ellipse(hdc, (int)px-5, (int)py+5, (int)px+5, (int)py+15);
		}
		else
		{
			MoveToEx(hdc, (int)px-10, (int)py-15, NULL);
			LineTo(hdc, (int)px-5, (int)py-5);
			MoveToEx(hdc, (int)px-10, (int)py-15, NULL);
			LineTo(hdc, (int)px-15, (int)py-5);
			
			MoveToEx(hdc, (int)px+10, (int)py-15, NULL);
			LineTo(hdc, (int)px+5, (int)py-5);
			MoveToEx(hdc, (int)px+10, (int)py-15, NULL);
			LineTo(hdc, (int)px+15, (int)py-5);
			
			MoveToEx(hdc, (int)px-5, (int)py+10, NULL);
			LineTo(hdc, (int)px+5, (int)py+10);
		}

		//此处可以添加文字信息,显示哲学家状态
		//Draw the left arm
		if (gChopstickState[pos] == pos)
		{
			AngRad = ((pos * dDeltaAng) + dDeltaAng / 2)/57.29577951;
			dx = CenterX + (sin(AngRad)*155);
			dy = CenterY - (cos(AngRad)*155);
		//	dx = CenterX + (px-CenterX)*155/180;
		//	dx = CenterY - (py-CenterY)*155/180;

			MoveToEx(hdc, (int)dx, (int)dy, NULL);
			AngRad = (pos * dDeltaAng)/57.29577951; //转化为弧度
			dx = CenterX + (sin(AngRad)*85);
			dy = CenterY - (cos(AngRad)*85);
			LineTo(hdc, (int)dx, (int)dy);
		}

		//Draw the right arm
		p1 = pos + 1;
		if (p1 == PHILOSOPHERS)
			p1 = 0;
		if (gChopstickState[p1] == pos)
		{
			AngRad = ((pos * dDeltaAng) + dDeltaAng / 2)/57.29577951;
			dx = CenterX + (sin(AngRad)*155);
			dy = CenterY - (cos(AngRad)*155);

			MoveToEx(hdc, (int)dx, (int)dy, NULL);
			AngRad = (p1 * dDeltaAng)/57.29577951;
			dx = CenterX + (sin(AngRad)*85);
			dy = CenterY - (cos(AngRad)*85);
			LineTo(hdc, (int)dx, (int)dy);
		}

		/* Delete the pen */
		DeleteObject(SelectObject(hdc, hPen));			
	}	//for pos

	BitBlt( hDestDC,
				rect.left,
				rect.top,
				rect.right - rect.left,
				rect.bottom-rect.top,
				hdc,
				rect.left,
				rect.top,
				SRCCOPY
			);
	GetLastError();

	SelectObject(hdc, hOldBitmap);

//	DeleteDC(hWndMain, hdc);
}

/********************************************************************/
/*	ROUTINE:	InitApplication										*/
/*																	*/
/*	PURPOSE:	Initialize the application							*/
/********************************************************************/

BOOL InitApplication(HINSTANCE hInstance)
{
	WNDCLASS  wc;

	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
	wc.lpszMenuName =  "din";
	wc.lpszClassName = "dinWClass";

	RegisterClass(&wc);

	return TRUE;
}


/********************************************************************/
/* ROUTINE:  InitInstance											*/
/*																	*/
/* PURPOSE:  Saves instance handle and creates main window			*/
/********************************************************************/

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	int ret;

	hInst = hInstance;

	hWndMain = CreateWindow(
		"dinWClass",		//窗口类名
		//"Dining Philosopher",
		"哲学家吃面",		//窗口标题
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		450,
		450,
		NULL, NULL, hInstance, NULL );

	if (!hWndMain)
		return FALSE;

	ShowWindow(hWndMain, nCmdShow);
	UpdateWindow(hWndMain);

	if (!CreateOffscreen())
		PostQuitMessage(1);

	ret = MessageBox(hWndMain, "你期望使用防死锁运行模式吗?\n\n"
		"如果选择Yes, 程序将正常运行.\n"
		"如果选择 No, 程序会进入死锁.\n",
		"Wait Mode", MB_YESNO);
	if (ret == IDYES)
		bWaitMultiple = TRUE;
	else
	{
		bWaitMultiple = FALSE;

		ret = MessageBox(hWndMain, "你期望快速进入死锁吗?\n\n"
			"如果选择Yes, 将更快进入死锁.\n",
			"Wait Mode", MB_YESNO);
		if (ret == IDYES)
			bFastFood = TRUE;
		else
			bFastFood = FALSE;
	}

	// Start the threads
	Diner();

	return TRUE;
}

/********************************************************************/
/* FUNCTION: WinMain												*/
/*																	*/
/* PURPOSE: Calls initialization function, processes message loop	*/
/********************************************************************/

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
	LPSTR lpCmdLine, int nCmdShow)
{
	MSG msg;
	int i;

	if (!hPrevInstance)
		if (!InitApplication(hInstance))
	   		return (FALSE);

	if (!InitInstance(hInstance, nCmdShow))
  		return (FALSE);

	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		TranslateMessage(&msg);
	 	DispatchMessage(&msg); 
	}
	// Clear the table
	for (i = 0; i < PHILOSOPHERS; i++)
		CloseHandle(gchopStick[i]); //关闭互斥体句柄
  	return (msg.wParam);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -