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

📄 readerandwriter.c

📁 本程序主要用于说明阅读者写入者问题中的资源互斥访问的调动策略
💻 C
字号:
/*
 * ReaderAndWriter.c
 *
 * Sample code for "Multithreading Applications in Win32"
 * This sample is discussed in Chapter 4.
 *
 * Graphically demonstrates the problem of the
 * ReaderAndWriter.
 */

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

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

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void RenderOffscreen(HDC hDestDC);
extern int Readercount;
extern int readerstate[CCounter];
extern int writerstate[CCounter];
extern int resourcestate[CCounter];
extern HANDLE count;
/********************************************************************/
/*	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);
				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; 
	int err=GetLastError();
	HBITMAP hOldBitmap	= SelectObject(hdc, hbmpOffscreen);
	RECT rect;
	HPEN hPen;
    int i;
	long CenterX, CenterY;

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

	GetClientRect(hWndMain, &rect);

	//Draw the resource
	CenterX = (rect.right - rect.left)/2;
	CenterY = (rect.bottom - rect.top)/2;
	Ellipse(hdc, CenterX -80, CenterY - 80, CenterX + 80, CenterY +80);
	DeleteObject(SelectObject(hdc, hPen));

	//draw the reader
	for(i=0;i<CCounter;i++)
	{
		/* select a pen for each reader */   
		switch (readerstate[i])
		{
		case resting:
			hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(0, 0, 0)));
			break;

		case waiting:
			hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(0, 255, 0)));
			break;
		case reading:
			hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(255, 0, 0)));
			break;

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

    	/* Draw the reader */
		Rectangle(hdc, CenterX+120*(i-2)-40,CenterY-200,CenterX+120*(i-2)+40,CenterY-150);

		//draw the right of reading
		if (resourcestate[i]==read)   
		{
			MoveToEx(hdc, CenterX,CenterY, NULL);
			LineTo(hdc, CenterX+120*(i-2),CenterY-175);
		}
	DeleteObject(SelectObject(hdc, hPen));	
	
	}	
  
//draw the writer
	for(i=0;i<CCounter;i++)
	{
		/* select a pen for each reader */   
		switch (writerstate[i])
		{
		case resting:
			hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(0, 0, 0)));
			break;

		case waiting:
			hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(0, 255, 0)));
			break;
		case writing:
			hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(255, 0, 0)));
			break;

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

    	/* Draw the writer */
		Rectangle(hdc, CenterX+120*(i-2)-40,CenterY+150,CenterX+120*(i-2)+40,CenterY+200);

		//draw the right of writing
		if (resourcestate[i]==write)   
		{
			MoveToEx(hdc, CenterX,CenterY, NULL);
			LineTo(hdc, CenterX+120*(i-2),CenterY+175);
		}
	DeleteObject(SelectObject(hdc, hPen));	
	
	}	

	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 =  "ReaderAndWriter";
	wc.lpszClassName = "ReaderAndWriterClass";

	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(
		"ReaderAndWriterClass",
		"ReaderAndWriter",
		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);
// Start the threads
	ReaderAndWriter();

	return TRUE;
}

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

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
	LPSTR lpCmdLine, int nCmdShow)
{   MSG msg;
	if (!hPrevInstance)
		if (!InitApplication(hInstance))
	   		return (FALSE);

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

	while (GetMessage(&msg, NULL, 0, 0))  
	{   //Processes messages
		TranslateMessage(&msg);
	 	DispatchMessage(&msg); 
	}
    CloseHandle(count);
	return (msg.wParam);
}

⌨️ 快捷键说明

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