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

📄 reader_writerdlg.cpp

📁 操作系统课程设计
💻 CPP
字号:
// Reader_WriterDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Reader_Writer.h"
#include "Reader_WriterDlg.h"

#include "fstream.h"
#include "Thread.h"
#include "conio.h"
#include "string.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


#define INTE_PER_SEC 1000
#define MAX_THREAD_NUM 64
#define MAX_FILE_NUM 32
#define MAX_STR_LEN 32
static int readcount ;
static int writecount ;
static CRITICAL_SECTION RP_Write;

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CReader_WriterDlg dialog

CReader_WriterDlg::CReader_WriterDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CReader_WriterDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CReader_WriterDlg)
	m_Filename = _T("");
	m_edit = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CReader_WriterDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CReader_WriterDlg)
	DDX_Text(pDX, IDC_EDIT1, m_Filename);
	DDX_Text(pDX, IDC_EDIT2, m_edit);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CReader_WriterDlg, CDialog)
	//{{AFX_MSG_MAP(CReader_WriterDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_EN_CHANGE(IDC_EDIT1, OnChangeEdit1)
	ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CReader_WriterDlg message handlers

BOOL CReader_WriterDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here

	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CReader_WriterDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CReader_WriterDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CReader_WriterDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CReader_WriterDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
	CFileDialog m_OpenDialog(TRUE,"doc",NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"文本文档(*.txt) | *.txt|Word文档(*.doc)|*.doc|All Files(*.*)| *.*|",NULL);
	m_OpenDialog.DoModal();	
	m_Filename = m_OpenDialog.GetPathName();
	UpdateData(FALSE);

}

void CReader_WriterDlg::OnChangeEdit1() 
{
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.
	
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	
}
//写者的处理函数
CString activity = "各进程的活动情况如下:\t\t\t\t   ";
void RP_WriterThread( LPVOID param)
{
	DWORD m_delay;
	DWORD m_persisit;
	int m_serial;
	char m_entity;
	//从参数中获得信息
	Thread * p = (Thread *) param; 
	m_serial = p->GetSerial();
	m_delay = (DWORD) (p->GetDelay())*INTE_PER_SEC;
	m_persisit = (DWORD) (p->GetPersist())*INTE_PER_SEC;
	m_entity = p->GetEntity();
	Sleep(m_delay) ;//延迟等待
	char display[50];
	sprintf(display,"%u\t%c\t%s\t\t    ",m_serial,m_entity,"发出写文件的请求!");
	activity += display;
    SetDlgItemText(AfxGetApp()->GetMainWnd()->GetSafeHwnd(),IDC_EDIT2,activity); 
	
	EnterCriticalSection(&RP_Write);
	//写文件
	sprintf(display,"%u\t%c\t%s\t\t    ",m_serial,m_entity,"已经开始写文件了!");
	activity += display;
    SetDlgItemText(AfxGetApp()->GetMainWnd()->GetSafeHwnd(),IDC_EDIT2,activity); 
	Sleep(m_persisit);
	//退出线程
	sprintf(display,"%u\t%c\t%s\t\t    ",m_serial,m_entity,"写文件已经完成了!");
	activity += display;
    SetDlgItemText(AfxGetApp()->GetMainWnd()->GetSafeHwnd(),IDC_EDIT2,activity); 
	LeaveCriticalSection(&RP_Write);
}

//读者的处理函数

void RP_ReaderThread(LPVOID param)
{
	HANDLE h_Mutex;
	h_Mutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");
	DWORD wait_for_mutex;
	DWORD m_delay;
	DWORD m_persisit;
	int m_serial;
	char m_entity;
	//从参数中获得信息
	Thread *p = (Thread *) param;
	m_serial = p->GetSerial();
	m_delay = (DWORD) (p->GetDelay())*INTE_PER_SEC;
	m_persisit = (DWORD) (p->GetPersist())*INTE_PER_SEC;
	m_entity = p->GetEntity();
	Sleep(m_delay); //延迟等待
	//该线程有活动了(有读要求)
	char display[50];
	sprintf(display,"%u\t%c\t%s\t\t    ",m_serial,m_entity,"发出读文件的请求!");
	activity += display;
    SetDlgItemText(AfxGetApp()->GetMainWnd()->GetSafeHwnd(),IDC_EDIT2,activity);
	//对Mutex进行互斥
	wait_for_mutex = WaitForSingleObject(h_Mutex,-1);
	readcount++;
	if(readcount == 1)
	{
		EnterCriticalSection(&RP_Write);  //第一个读者在没有写者的情况下进入临界区
	}
	ReleaseMutex(h_Mutex);
	sprintf(display,"%u\t%c\t%s\t\t    ",m_serial,m_entity,"已经开始读文件了!");
	activity += display;
	SetDlgItemText(AfxGetApp()->GetMainWnd()->GetSafeHwnd(),IDC_EDIT2,activity);
	//进程有了读的活动
	Sleep(m_persisit);
	//退出线程
	sprintf(display,"%u\t%c\t%s\t\t    ",m_serial,m_entity,"已经读完文件了 !");
	activity += display;
	SetDlgItemText(AfxGetApp()->GetMainWnd()->GetSafeHwnd(),IDC_EDIT2,activity);
	wait_for_mutex = WaitForSingleObject(h_Mutex,1);
	readcount--;
	if(readcount == 0)
	{
		LeaveCriticalSection(&RP_Write); //最后一个读者释放临界区
	}
	ReleaseMutex(h_Mutex);

}
void CReader_WriterDlg::ReaderPriority(CString name)
{
	DWORD n_thread = 0;
	DWORD thread_id;
	DWORD wait_for_all;
	HANDLE h_Mutex;
	int n_serial;
	char c_entity;
	float f_delay;
	float f_persist;
	h_Mutex = CreateMutex(NULL,FALSE,"mutex_for_readcount");

	HANDLE h_thread[MAX_THREAD_NUM];   //定义线程句柄
	Thread *Thread_info[MAX_THREAD_NUM];  //记录线程的信息

	readcount = 0;
	InitializeCriticalSection(&RP_Write);
	ifstream  in;
	in.open(m_Filename);
	while(!in.eof())
	{
		in>>n_serial;
		in>>c_entity;
		in>>f_delay;
        in>>f_persist;
		Thread_info[n_thread] = new Thread(n_serial,c_entity,f_delay,f_persist);
		n_thread++;
	}
	in.close();
	for(int i = 0;i < (int)(n_thread);i++)
	{
		if(Thread_info[i]->GetEntity() == 'R'||Thread_info[i]->GetEntity() == 'r')
		{
			h_thread[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)RP_ReaderThread,Thread_info[i],0,&thread_id);
		}
		if(Thread_info[i]->GetEntity() == 'W'||Thread_info[i]->GetEntity() == 'w')
		{
			h_thread[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)RP_WriterThread,Thread_info[i],0,&thread_id);
		}
	}
	//等待所有的进程完成它的活动
	wait_for_all = WaitForMultipleObjects(n_thread,h_thread,FALSE,0);

}


void CReader_WriterDlg::OnButton3() 
{
	// TODO: Add your control notification handler code here
	if(m_Filename.IsEmpty())
	{
		MessageBox("你还没有选择文件呢!:p","提示",MB_ICONHAND|MB_RETRYCANCEL);
		return;
	}
	else 	ReaderPriority(m_Filename);
}

⌨️ 快捷键说明

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