标签:时间 type 状态 cas seh ESS controls 模型 memset
1965年dijkstra提出了一个关于进程同步问题,大致意思如下:
有5个哲学家坐在一张圆桌上,每个哲学家左右两边各有一个叉子。
只有当集齐两个叉子,才能够吃饭,否则哲学家就得乖乖去思考。
桌子上就5个叉子,理论上同时可以让两个哲学家进餐,那么怎么用两个进程来模拟这个状态呢?
0x001
这几个哲学家可以视作一个进程开了5次。我们来创建一个哲学家进程,代码如下:
用_tagCOMMUNICATIONOBJECT存放公共的数据,放在公共的内存中。
#include "stdafx.h"
#include <Windows.h>
#include<iostream>
#define EATING_TIME 1000
#define PHILOSOPHER_COUNT 5
#define WM_INVALIDATE WM_USER + 1
//公用的数据,放到映射的内存中的数据
using namespace std;
typedef struct _tagCOMMUNICATIONOBJECT
{
HWND hWnd;
bool bExitApplication;
int iPhilosopherArray[PHILOSOPHER_COUNT];
int PhilosopherCount;
} COMMUNICATIONOBJECT, * PCOMMUNICATIONOBJECT;
void Eat();//吃饭饭
TCHAR* szSemaphoreName = TEXT("__PD_SEMAPHORE__");//信号量名称
TCHAR* szMappingName = TEXT("__SHARED_FILE_MAPPING__");//映射内存名称
bool bExitApplication = false;//退出应用标志
int _tmain(int argc, _TCHAR* argv[])
{
//获取控制台句柄
HWND Hconsole = GetConsoleWindow();
ShowWindow(Hconsole, SW_HIDE);//隐藏控制台窗口
int index = (int)_tcstol(argv[0], NULL, 10);//获取当前进程代号
//读取映射内容
HANDLE hMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szMappingName);
if (!hMapping)
{
cout << "hMapping打开失败!" << endl;
cout << GetLastError() << endl;
return -1;
}//映射内容一旦打开,未关闭时,一直处于可操作状态
while (!bExitApplication)
{
//打开信号量
HANDLE hSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, szSemaphoreName);
if (!hSemaphore)
{
cout << "sempahore创建失败!" << endl;
cout << GetLastError() << endl;
return -1;
}
//等待信号量触发
WaitForSingleObject(hSemaphore, INFINITE);//等待信号对象
//从映射对象中读取通用变量
PCOMMUNICATIONOBJECT pcomobj = (PCOMMUNICATIONOBJECT)MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS,
0, 0, sizeof(COMMUNICATIONOBJECT));
if (!pcomobj)
{
cout << "pcomobj创建失败!" << endl;
cout << GetLastError() << endl;
return -1;
}
bExitApplication = pcomobj->bExitApplication;//获取循环标志
if (!pcomobj->iPhilosopherArray[(index + pcomobj->PhilosopherCount - 1) % pcomobj->PhilosopherCount] &&
!pcomobj->iPhilosopherArray[(index + pcomobj->PhilosopherCount + 1) % pcomobj->PhilosopherCount])
{
pcomobj->iPhilosopherArray[index] = 1;
Eat();//吃饭
}
SendMessage(pcomobj->hWnd, WM_INVALIDATE, 0, 0);//向另一个窗口发送消息
pcomobj->iPhilosopherArray[index] = 0;//吃完饭置为0
ReleaseSemaphore(hSemaphore, 1, NULL);//针对一个信号量
UnmapViewOfFile(pcomobj);//关闭文件映射
CloseHandle(hSemaphore);//关闭信号量句柄
}
CloseHandle(hMapping);//关闭文件映射句柄
return 0;//返回
}
void Eat()
{
Sleep(EATING_TIME);//停顿一段时间用于吃饭
}
0x02
创建一个进程来控制哲学家进餐
#include "stdafx.h"
#include<iostream>
using namespace std;
#define BUTTON_CLOSE 100
#define PHILOSOPHER_COUNT 5
#define WM_INVALIDATE WM_USER + 1
typedef struct _tagCOMMUNICATIONOBJECT
{
HWND hWnd;
bool bExitApplication;
int iPhilosopherArray[PHILOSOPHER_COUNT];
int PhilosopherCount;
} COMMUNICATIONOBJECT, *PCOMMUNICATIONOBJECT;
HWND InitInstance(HINSTANCE hInstance, int nCmdShow);
ATOM MyRegisterClass(HINSTANCE hInstance);
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int PhilosopherPass(int iPhilosopher);
void FillEllipse(HWND hWnd, HDC hDC, int iLeft, int iTop, int iRight, int iBottom, int iPass);
TCHAR* szTitle = TEXT("Philosophers Dinner Demo");
TCHAR* szWindowClass = TEXT("__PD_WND_CLASS__");
TCHAR* szSemaphoreName = TEXT("__PD_SEMAPHORE__");
TCHAR* szMappingName = TEXT("__SHARED_FILE_MAPPING__");
PCOMMUNICATIONOBJECT pCommObject = NULL;
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
//未使用的变量不出现警告
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
HANDLE hMapping = CreateFileMapping((HANDLE)-1, NULL,
PAGE_READWRITE, 0, sizeof(COMMUNICATIONOBJECT), szMappingName);
if (!hMapping)
{
cout << "hMapping为空!" << endl;
cout << GetLastError() << endl;
return -1;
}
pCommObject = (PCOMMUNICATIONOBJECT)MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (!pCommObject)
{
cout << "pcommobject为空!" << endl;
cout << GetLastError() << endl;
return -1;
}
HANDLE hSemaphore = CreateSemaphore(NULL, (PHILOSOPHER_COUNT / 2),
(PHILOSOPHER_COUNT / 2),szSemaphoreName);
if (!hSemaphore)
{
cout << "hsemaphore为空!" << endl;
cout << GetLastError() << endl;
return -1;
}
InitCommonControls();//初始化通用控件
MyRegisterClass(hInstance);//注册
HWND hwnd = InitInstance(hInstance,nCmdShow);//初始化
if (!hwnd)
{
cout << "hwnd为空!" << endl;
cout << GetLastError() << endl;
return -1;
}
pCommObject->hWnd = hwnd;
pCommObject->bExitApplication = false;
pCommObject->PhilosopherCount = PHILOSOPHER_COUNT;
memset(pCommObject->iPhilosopherArray, 0,sizeof(*pCommObject->iPhilosopherArray));
//开启进程
STARTUPINFO starupinfo[PHILOSOPHER_COUNT] = { {0},{0},{0},{0},{0} };
PROCESS_INFORMATION processInfo[PHILOSOPHER_COUNT]= { {0},{0},{0},{0},{0} };
HANDLE hProcess[PHILOSOPHER_COUNT] = { 0 };
TCHAR szBuffer[8] = {0};
for (int i = 0; i < PHILOSOPHER_COUNT; i++)
{
wsprintf(szBuffer, TEXT("%d"), i);
if (CreateProcess(TEXT("..\\Debug\\Philosopher.exe"), szBuffer, NULL,
NULL,
FALSE,
NULL,
NULL,
NULL,
&starupinfo[i],
&processInfo[i]))
{
hProcess[i] = processInfo[i].hProcess;
}
}
MSG msg = { 0 };
while (GetMessage(&msg, hwnd, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
pCommObject->bExitApplication = true;
UnmapViewOfFile(pCommObject);//关闭文件映射
for (int i = 0; i < PHILOSOPHER_COUNT; i++)
{
CloseHandle(hProcess[i]);//关闭进程句柄
}
CloseHandle(hMapping);
return (int)msg.wParam;//返回消息参数0
}
//ATOM==word
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wndEx;
wndEx.cbSize = sizeof(WNDCLASSEX);
wndEx.style = CS_HREDRAW | CS_VREDRAW;
wndEx.lpfnWndProc = WndProc;
wndEx.cbClsExtra = 0;
wndEx.cbWndExtra = 0;
wndEx.hInstance = hInstance;
wndEx.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wndEx.hCursor = LoadCursor(NULL, IDC_ARROW);
wndEx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndEx.lpszMenuName = NULL;
wndEx.lpszClassName = szWindowClass;
wndEx.hIconSm = LoadIcon(wndEx.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
return RegisterClassEx(&wndEx);
}
//初始化
HWND InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPED | WS_CAPTION
| WS_SYSMENU | WS_MINIMIZEBOX, 200, 200, 540, 590, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return NULL;
}
HFONT hFont = CreateFont(14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, BALTIC_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_MODERN, TEXT("Microsoft Sans Serif"));
HWND hButton = CreateWindow(TEXT("BUTTON"), TEXT("Close"), WS_CHILD | WS_VISIBLE
| BS_PUSHBUTTON | WS_TABSTOP, 410, 520, 100, 25, hWnd, (HMENU)BUTTON_CLOSE, hInstance, NULL);
SendMessage(hButton, WM_SETFONT, (WPARAM)hFont, TRUE);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return hWnd;
}
//回调函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case BUTTON_CLOSE:
{
DestroyWindow(hWnd);
break;
}
}
break;
}
case WM_INVALIDATE:
{
//更新指定的窗口区域
InvalidateRect(hWnd, NULL, TRUE);//接受philosopher发来的消息,进行处理
break;
}
case WM_PAINT:
{
PAINTSTRUCT paintStruct;
HDC hDC = BeginPaint(hWnd, &paintStruct);
FillEllipse(hWnd, hDC, 210, 10, 310, 110, PhilosopherPass(1));//圆圈1
FillEllipse(hWnd, hDC, 410, 170, 510, 270, PhilosopherPass(2));//圆圈2
FillEllipse(hWnd, hDC, 335, 400, 435, 500, PhilosopherPass(3));//圆圈3
FillEllipse(hWnd, hDC, 80, 400, 180, 500, PhilosopherPass(4));//圆圈4
FillEllipse(hWnd, hDC, 10, 170, 110, 270, PhilosopherPass(5));//圆圈5
EndPaint(hWnd, &paintStruct);//结束绘制
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
return 0;
}
//哲学家
int PhilosopherPass(int iPhilosopher)
{
return pCommObject->iPhilosopherArray[iPhilosopher - 1];
}
//填充圆圈
void FillEllipse(HWND hWnd, HDC hDC, int iLeft, int iTop, int iRight, int iBottom, int iPass)
{
HBRUSH hBrush = NULL;
if (iPass)//哲学家状态非0,填充红色
{
hBrush = CreateSolidBrush(RGB(255, 0, 0));
}
else//哲学家状态为0,填充白色
{
hBrush = CreateSolidBrush(RGB(255, 255, 255));
}
HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);//选中画刷1
Ellipse(hDC, iLeft, iTop, iRight, iBottom);//绘制圆形
SelectObject(hDC, hOldBrush);//填充颜色
DeleteObject(hBrush);//用完之后清空选中的句柄
}
标签:时间 type 状态 cas seh ESS controls 模型 memset
原文地址:https://www.cnblogs.com/yuanshijie/p/12350693.html