📄 dining.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 + -