课程设计报告
( 2009--2010年度第二学期)
课程名称:操作系统实验
课设题目: 用位示图管理磁盘空间的分配与回收
院系:控制与计算机工程学院
班级:
姓名:
指导教师:李为
设计周数: 一周
成绩:
2010年7月9 日
一、需求分析
要求打印或显示程序运行前和运行后的位示图,以及分配和回收磁盘的物理地址过程。
(1)假定现有一个磁盘组,共40个柱面。每个柱面4个磁道,每个磁道又划分成4个物理记录。磁盘的空间使用情况用位示图表示。位示图用若干个字构成,每一位对应一个磁盘块。1表示占用,0表示空闲。为了简单,假定字长为16位,其位示图如图9—1所示。系统设一个变量S,记录磁盘的空闲块个数。
(2)申请一个磁盘块时,由磁盘块分配程序查位示图,找出一个为0的位,并计算磁盘的物理地址(即求出柱面号、磁道号(也即磁头号)和扇区号)。
由位示图计算磁盘的相对块号的公式如下:
相对块号一字号×16+位号
之后再将相对块号转换成磁盘的物理地址:
由于一个柱面包含的扇区数=每柱面的磁道数×每磁道的扇区数=4×4=16,故柱面号=相对块号/16的商,即柱面号=字号
磁道号=(相对块号/16的余数)/4的商,即(位号/4)的商
物理块号=(相对块号/16的余数)/4的余数,即(位号/4)的余数
(3)当释放一个相对物理块时,运行回收程序,计算该块在位示图中的位置,再把相应位置0。计算公式如下:
先由磁盘地址计算相对块号:
相对块号=柱面号×16+磁道号×4+物理块号
再计算字号和位号:
字号=相对块号/16的商,也即字号=柱面号
位号=磁道号×物理块数/每磁道+物理块号
(4)按照用户要求,申请分配一系列磁盘块,运行分配程序,完成分配。然后将分配的相对块号返回用户,并将相对块号转换成磁盘绝对地址,再显示系统各表和用户已分配的情况。
(5)设计一个回收算法,将上述已分配给用户的各盘块释放。并显示系统各表。回收算法框图如图5所示。
二、整体功能及设计
程序整体主要有三个功能模块,分别是:初使化、分配以及回收。当点击相应按钮时实现其功能。
使用二维数组array1_after[50][16]、array1_before[50][16]、array2_after[50][16]分别记录分配前、分配后、回收后的位示图的使用情况,使用表格m_list1_after 、m_list1_before 、m_listafter 显示位示图的使用情况。
程序设计了三个方法,分别是初始化OnInitDialog()、分配算法OnButtonFp()、回收算法OnButtonHs()。
磁盘空间分配框图如图1所示, 磁盘空间回收框图如图2所示.
图1 磁盘空间分配框图 图2 磁盘空间回收框图
三、编程实现
#include "stdafx.h"
#include "FENPEIYUHUISHOU.h" #include "FENPEIYUHUISHOUDlg.h"
#include "HuishouDlg.h" #ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
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
}
CFENPEIYUHUISHOUDlg::CFENPEIYUHUISHOUDlg(CWnd* pParent /*=NULL*/)
: CDialog(CFENPEIYUHUISHOUDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CFENPEIYUHUISHOUDlg)
m_kongxian = 0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CFENPEIYUHUISHOUDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFENPEIYUHUISHOUDlg)
DDX_Control(pDX, IDC_LIST2_AFTER, m_list2_after);
DDX_Control(pDX, IDC_LIST1_ON, m_list1_on);
DDX_Control(pDX, IDC_LIST1_BEFORE, m_list1_before);
DDX_Control(pDX, IDC_LIST1_AFTER, m_list1_after);
DDX_Text(pDX, IDC_EDIT_KONGXIAN, m_kongxian);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CFENPEIYUHUISHOUDlg, CDialog) //{{AFX_MSG_MAP(CFENPEIYUHUISHOUDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_FP, OnButtonFp)
ON_BN_CLICKED(IDC_BUTTON_HS, OnButtonHs)
ON_BN_CLICKED(IDC_BUTTON_INIT, OnButtonInit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CFENPEIYUHUISHOUDlg::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
DWORD dwExStyle = LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT;
m_list1_before.SetExtendedStyle(dwExStyle);
m_list1_after.SetExtendedStyle(dwExStyle);
m_list2_after.SetExtendedStyle(dwExStyle);
m_list1_on.SetExtendedStyle(dwExStyle);
for(int i=15;i>=0;i--)
{
CString str;
str.Format("%d",i);
m_list1_before.InsertColumn(0,str,LVCFMT_CENTER,30);
m_list1_after.InsertColumn(0,str,LVCFMT_CENTER,30);
m_list2_after.InsertColumn(0,str,LVCFMT_CENTER,30);
}
m_list1_on.InsertColumn(0,"相对块号",LVCFMT_CENTER,60);
m_list1_on.InsertColumn(1,"柱面号",LVCFMT_CENTER,60);
m_list1_on.InsertColumn(2,"磁道号",LVCFMT_CENTER,60);
m_list1_on.InsertColumn(3,"物理块号",LVCFMT_CENTER,60);
m_list1_on.InsertColumn(4,"字号",LVCFMT_CENTER,40);
m_list1_on.InsertColumn(5,"位号",LVCFMT_CENTER,40);
return TRUE; // return TRUE unless you set the focus to a control }
void CFENPEIYUHUISHOUDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CFENPEIYUHUISHOUDlg::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();
}
}
HCURSOR CFENPEIYUHUISHOUDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CFENPEIYUHUISHOUDlg::OnButtonFp()
{
// TODO: Add your control notification handler code here
int index=0;
int flag =1,m=0,n=0;
int count=0;
for(m=0;m { for(n=0;n<16;n++) { if(array1_after[m][n]==0) { flag = 0; break; } } if(flag == 0) break; } array1_after[m][n]=1; CString str; int k=0; int i,j; for(i=0;i { str.Format("%d",array1_after[i][0]); } for(i=0;i { m_list1_after.InsertItem(i,str); for(j=0;j<16;j++) { CString str; str.Format("%d",array1_after[i][j]); array2_after[i][j]=array1_after[i][j]; if(array1_after[i][j]==0) count++; m_list1_after.SetItemText(i,j,str); } } str.Format("%d",m*16+n); m_list1_on.InsertItem(index,str); str.Format("%d",m); m_list1_on.SetItemText(index,1,str); m_list1_on.SetItemText(index,4,str); str.Format("%d",n/b); m_list1_on.SetItemText(index,2,str); str.Format("%d",n%b); m_list1_on.SetItemText(index,3,str); str.Format("%d",n); m_list1_on.SetItemText(index,5,str); index++; m_kongxian=m_kongxian-1; if(m_kongxian<0){ AfxMessageBox("无空闲块!请回收后再使用!");} UpdateData(FALSE); } void CFENPEIYUHUISHOUDlg::OnButtonHs() { // TODO: Add your control notification handler code here UpdateData(TRUE); CHuishouDlg dlg; int num=0; int m=0,n=0; CString str; if(dlg.DoModal()==IDOK) { num=dlg.m_it1*16+dlg.m_it2*b+dlg.m_it3; m=dlg.m_it1; n=dlg.m_it2*b+dlg.m_it3; } array2_after[m][n]=0; for(int i=0;i { str.Format("%d",array2_after[i][0]); } for(int x=0;x { m_list2_after.InsertItem(x,str); for(int y=0;y<16;y++) { CString str; str.Format("%d",array2_after[x][y]); m_list2_after.SetItemText(x,y,str); } } m_kongxian=m_kongxian+1; for(i=0;i { CString o=m_list1_on.GetItemText(i,0); CString str1; str1.Format("%d",num); if(str1==o) { m_list1_on.DeleteItem(i); } } UpdateData(FALSE); } void CFENPEIYUHUISHOUDlg::OnButtonInit() { // TODO: Add your control notification handler code here UpdateData(TRUE); CInitDlg dlg; int count=0; if(dlg.DoModal()==IDOK) { a=dlg.m_it1; b=dlg.m_it2; c=dlg.m_it3; CString str; int m,n; int k=0;