实验(一) Windows 7基本操作
一、实验目的
1.掌握文件和文件夹基本操作。
2.掌握“资源管理器”和“计算机”基本操作。
二、实验要求
1.请将操作结果用Alt+Print Screen组合键截图粘贴在题目之后。
2.实验完成后,请将实验报告保存并提交。
三、实验内容
1.文件或文件夹的管理(提示:此题自行操作一遍即可,无需抓图)★期末机试必考题★
(1) 在D:盘根目录上创建一个名为“上机实验”的文件夹,在“上机实验”文件夹中创建1个名为“操作系统上机实验”的空白文件夹和2个分别名为“2.xlsx”和“3.pptx”的空白文件,在“操作系统上机实验”文件夹中创建一个名为“1.docx”的空白文件。
(2) 将“1.docx”改名为“介绍信.docx”;将“上机实验”改名为“作业”。
(3) 在“作业”文件夹中分别尝试选择一个文件、同时选择两个文件、一次同时选择所有文件和文件夹。
(4) 将“介绍信.docx”复制到C:盘根目录。
(5) 将D:盘根目录中的“作业”文件夹移动到C:盘根目录。
(6) 将“作业”文件夹中的“2.xlsx”文件删除放入“回收站”。
(7) 还原被删除的“2.xlsx”文件到原位置。
2.搜索文件或文件夹,要求如下:
查找C盘上所有以大写字母“A”开头,文件大小在10KB以上的文本文件。(提示:搜索时,可以使用“?”和“*”。“?”表示任意一个字符,“*”表示任意多个字符。)
3. 在桌面上为C:盘根目录下的“作业”文件夹创建一个桌面快捷方式。★期末机试必考题★
3.“计算机”或“资源管理器”的使用
(1) 在“资源管理器”窗口,设置以详细信息方式显示C:\WINDOWS中所有文件和文件夹,使所有图标按类型排列显示,并不显示文件扩展名。(提示:三步操作全部做完后,将窗口中显示的最终设置结果抓一张图片即可)
(2) 将C:盘根目录中 “介绍信.docx” 的文件属性设置为“只读”和“隐藏”,并设置在窗口中显示“隐藏属性”的文件或文件夹。(提示:请将“文件夹”对话框中选项设置效果与C:盘根目录中该文件图标呈现的半透明显示效果截取在一整张桌面图片中即可)
4.回收站的设置
设置删除文件后,不将其移入回收站中,而是直接彻底删除功能。
第二篇:操作系统实验报告
东北大学秦皇岛分校
计算机与通信工程学院
操作系统课程设计
设计题目FCFS调度算法模拟和进程管理器
课程设计任务书
专业:计算机科学与技术 学号:2133319 学生姓名(签名):
设计题目:FCFS调度算法模拟及进程管理器
一、设计实验条件
808实验室
二、设计任务及要求
1. FCFS调度算法的模拟实现;
要求:提供10个模拟作业,在屏幕上打印所提供的作业信息,输入进程名作业被放入就绪队列,程序根据FCFS调度算法,对就绪队列中的进程进行调度执行,每个模拟进程执行时打印自身的进程名、到达时间等信息,最后要打印出所调度作业的平均周转时间和平均带权周转时间
2. 进程管理器;
要求:实现一个系统进程管理器,能够显示当前系统的活动进程信息(进程名、用户、优先级、内存使用等),并能结束或创建特定进程。
三、前言
融会贯通计算机操作系统课程的内容,通过知识的综合运用,加深对计算机操作系统工作原理及相互联系的认识;
掌握进程调度的实现以及原理
培养使用代码模拟操作系统功能的能力,同时加深对操作系统的认识
四、设计主体
1. FCFS调度算法的模拟实现(该部分由组员自己独立完成)
1) 设计内容
建立数据结构,提供10个模拟作业,在屏幕上打印所提供的作业信息,输入进程名作业被放入就绪队列,程序根据FCFS调度算法,对就绪队列中的进程进行调度执行,每个模拟进程执行时打印自身的进程名、到达时间等信息,最后要打印出所调度作业的平均周转时间和平均带权周转时间。和其他调度算法相比较,分析该调度算法的优缺点。
2) 分析
使用java语言模拟进程调度的FCFS算法。算法的核心思想是:根据进程进入就绪队列的到达时间前后顺序来进行处理机调度。先到的进程,有限享受处理机,直到该进程执行完毕或因某事发生等待,而释放处理机。
设计思路:为进程建立一个类PCB,其中包含进程名、到达时间、服务时间、开始执行时间、完成时间、周转时间、带权周转时间7个属性。程序初始化时,创建10个PCB对象,每个对象仅初始化进程名和服务时间。之后通过从控制台输入进程名的顺序来决定10个进程进入就绪队列的顺序,也就是处理的顺序。其中周转时间=完成时间-到达时间,带权周转时间=周转时间/服务时间
3) 结论
先来先服务调度算法,有利于长作业,不利于短作业。从运行结果中可以看出短作业带权周转时间明显偏高,该算法有利于CPU繁忙型作业,不利于IO繁忙型作业
4) 代码
以下是进程PCB的代码:
publicclass PCB {
private String name;//进程名
privateint reachTime;//到达时间 (由给进行命名的顺序决定)
privateint serviceTime;//服务时间
privateint startTime;//开始执行时间
privateint finishTime;//完成时间
privateint turnaroundTime;//周转时间 = 完成时间-到达时间
privatedouble turnaroundTimeWithWeight;//带权周转时间=周转时间/服务时间
public PCB()
{
this.name="";
}
/**
* 初始化时 已知 服务时间
*
*/
public PCB(String name ,int serviceTime)
{
this.name = name;
this.serviceTime = serviceTime;
}
/*
* get/set方法组
*
*/
public String getName() {
return name;
}
publicvoid setName(String name) {
this.name = name;
}
publicint getReachTime() {
return reachTime;
}
publicvoid setReachTime(int reachTime) {
this.reachTime = reachTime;//设置到达时间
}
publicint getServiceTime() {
return serviceTime;
}
publicvoid setServiceTime(int serviceTime) {
this.serviceTime = serviceTime;
}
publicint getStartTime() {
return startTime;
}
publicvoid setStartTime(int startTime) {
this.startTime = startTime;
if(this.startTime>=0)
{
this.finishTime = this.startTime+this.serviceTime; //设置完成时间
this.turnaroundTime = this.finishTime-this.reachTime; //设置周转时间
this.turnaroundTimeWithWeight = 1.0*this.turnaroundTime/this.serviceTime;//设置带权周转时间
}
}
publicint getFinishTime() {
return finishTime;
}
publicint getTurnaroundTime() {
return turnaroundTime;
}
publicdouble getTurnaroundTimeWithWeight() {
return turnaroundTimeWithWeight;
}
/**
* 打印进程信息
*/
publicvoid printMSG()
{
System.out.println(this.name+"\t"+this.reachTime+"\t"+this.serviceTime+"\t "
+this.startTime+"\t\t"
+this.finishTime+"\t"
+this.turnaroundTime+"\t"
+(Double.parseDouble(new DecimalFormat("#.##").format(this.turnaroundTimeWithWeight)))
);
}}
FCFS算法的核心功能代码:
publicclass FCFS {
/**
* 创建10个作业
*/
public PCB[] init()
{
PCB[] pcbs = new PCB[]{
new PCB("A",1),
new PCB("B",100),
new PCB("C",1),
new PCB("D",100),
new PCB("E",22),
new PCB("F",33),
new PCB("G",11),
new PCB("H",44),
new PCB("I",55),
new PCB("J",66),
};
return pcbs;
}
/**
* 打印作业信息
*
*/
public void printPCB(PCB[] pcbs)
{
System.out.println("作业名\t\t服务时间");
for(int i=0;i<pcbs.length;i++)
{
System.out.println(pcbs[i].getName()+"\t\t"+pcbs[i].getServiceTime());
}
}
privateboolean isContain(String name)
{
return "ABCDEFGHIJ".contains(name);
}
/**
*避免重复输入进程名
*
*/
privateboolean isInclude(List<PCB> list,String name)
{
for(PCB p : list)
{
if(p.getName().equals(name))
{
returntrue;
}
}
returnfalse;
}
/**
* 将作业按照一定顺序加入就绪队列
*
*/
publicvoid selectPCB(List<PCB> list,PCB[] pcbs)
{
Scanner console = new Scanner(System.in);
Map<String,PCB>map = new HashMap<String,PCB>();
for(int i=0;i<pcbs.length;i++)
{
map.put(pcbs[i].getName(), pcbs[i]);
}
int i=0; //初始的到达时间默认是0
while(true)
{
System.out.println("请输入第"+(i+1)+"个进程名");
String name = console.nextLine();
if(!isContain(name))
{
System.out.println("请输入正确的进程名");
continue;
}
elseif(!isInclude(list,name))
{
PCB p = map.get(name);
p.setReachTime(i); //设置进程到达时间
if(i==0)//第一个加入到就绪队列,设置开始执行时间
{
p.setStartTime(i);
}
else
{
int before = list.get(i-1).getFinishTime();
if(before<p.getReachTime())
{
System.out.println("开始执行时间小于到达时间,逻辑错误!");
break;
}
p.setStartTime(before);
}
list.add(p);
if(++i>=10)
{
break;
}
}
else
{
System.out.println("请不要重复输入");
continue;
}
}
}
publicvoid runPCB(List<PCB> list)
{
int sumTurnaround=0;
double sumTurnaroundWithWeight=0;
System.out.println("进程名\t到达时间\t服务时间\t开始执行时间\t完成时间\t周转时间\t带权周转时间");
for(PCB p:list)
{
try {
Thread.sleep(300);
p.printMSG();
sumTurnaround+=p.getTurnaroundTime();
sumTurnaroundWithWeight+=p.getTurnaroundTimeWithWeight();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("平均周转时间:"
+Double.parseDouble(new DecimalFormat("#.##").format(1.0*sumTurnaround/list.size()))+"---平均带权周转时间:"
+Double.parseDouble(new DecimalFormat("#.##").format(sumTurnaroundWithWeight/list.size())));}}
5) 结果展示:
2. 进程管理器
1) 设计内容
Windows系统环境下,实现一个系统进程管理器,能够显示当前系统的活动进程信息(进程名、用户、优先级、内存使用等),并能结束或创建特定进程。
2) 分析
使用c#进行可视化编程,参照windows的任务管理器设计窗体;窗体功能包括应用程序、进程、性能。分别显示当前系统正在运行的程序、进程以及磁盘使用情况。通过使用windowsAPI来调用系统接口函数,以获取系统信息。本人负责程序的逻辑控制和主要程序调用API的实现(主要设计项目中SystemUtils类),其中部分功能代码仿照网上的代码编写完成。
3) 结论
重点掌握通过API来编程,熟悉函数的功能原理,注意控件之间的关系,认真调试代码,提高代码实现能力
4) 代码
主窗体代码:
public partial class mainForm : Form
{
SystemUtils sInfo; //系统信息类
DateTime lastSysTime; //最后刷新时间, 用于计算进程 CPU 利用率
public mainForm()
{
InitializeComponent();
}
private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void 运行新程序ToolStripMenuItem_Click(object sender,EventArgs e)
{
Process newProcess = new Process(); //新建程序
newProcess.StartInfo.FileName = "rundll32.exe";//指定程序名字
newProcess.StartInfo.Arguments = "shell32.dll #61";//指定参数
newProcess.Start();//运行程序
}
private void 关于作者ToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("本程序由21333班17号、18号、19号、20号合力完成");
}
private void tmrProcess_Tick(object sender, EventArgs e)
{
int oldWorkingSet = 0; //记录进程旧的内存大小
int oldTimePercent = 0; //记录进程旧的CPU百分比
int newTimePercent = 0; //记录进程新的CPU百分比
int ProcessCount = ProcessView.Items.Count; //获取进程listview中的项数
TimeSpan ts = (TimeSpan)(DateTime.Now - lastSysTime); //计算时间间隔
double sysTimeSpan = ts.TotalMilliseconds;//时间间隔数
Hashtable htProcess = new Hashtable(); //进程哈希表
List<ProcessInfo> pInfo = sInfo.GetProcessInfo(); //获取当前系统进程列表
for (int i = 0; i < pInfo.Count; i++)
{
htProcess.Add(pInfo[i].ProcessID.ToString(), pInfo[i].ProcessID);
ListViewItem item = ProcessCount>0 ? ProcessView.FindItemWithText(pInfo[i].ProcessID.ToString(), false, 0, false) : null;
if (item != null) //找到节点则更新
{
double processorTimeSpan = (double)Math.Abs(pInfo[i].ProcessorTime - (double)item.Tag);
if (sysTimeSpan != 0)
{
processorTimeSpan = processorTimeSpan / sysTimeSpan;
newTimePercent = (int)(processorTimeSpan * 100 / sInfo.CpuCount);
if (newTimePercent == 100)
{
newTimePercent = 99;
}
}
else
{
newTimePercent = 0;
}
oldTimePercent = int.Parse(item.SubItems[2].Text);
if (newTimePercent != oldTimePercent)
{
item.SubItems[2].Text = string.Format("{0:00}", newTimePercent);
}
oldWorkingSet = int.Parse(item.SubItems[3].Text);
if (pInfo[i].WorkingSet != oldWorkingSet)
{
item.SubItems[3].Text = pInfo[i].WorkingSet.ToString();
}
item.Tag = pInfo[i].ProcessorTime;
}
else //否则添加节点
{
item = new ListViewItem(pInfo[i].ProcessID.ToString());
item.SubItems.Add(pInfo[i].ProcessName);
item.SubItems.Add(string.Format("{0:00}", 0));
item.SubItems.Add(pInfo[i].WorkingSet.ToString());
item.SubItems.Add(pInfo[i].ProcessPath);
item.Tag = pInfo[i].ProcessorTime;
ProcessView.Items.Add(item); //add
}
}
//删除过时的进程
if (ProcessView.Items.Count != htProcess.Count)
{
foreach (ListViewItem tem in ProcessView.Items)
{
if (!htProcess.ContainsKey(tem.Text))
{
ProcessView.Items.Remove(tem);
}
}
}
//更新最后刷新时间
lastSysTime = DateTime.Now;
process.Text = string.Format("进程数: {0}", htProcess.Count); //刷新状态栏进程个数
}
private void tmrSysInfo_Tick(object sender, EventArgs e)
{
//刷新cpu, 内存信息 刷新状态栏
float cpuLoad = sInfo.CpuLoad;
cpu.Text = string.Format("CPU 使用: {0:f}%", cpuLoad);
long pMemory = sInfo.PhysicalMemory;
long aMemory = sInfo.MemoryAvailable;
long lMemory = pMemory - aMemory;
memory.Text = string.Format("内存使用: {0}/{1} Bytes", lMemory, pMemory);
}
private void 刷新_Click(object sender, EventArgs e)
{
APPView.Items.Clear();
List<string> Apps = SystemUtils.FindAllApps(this.Handle.ToInt32());
foreach (string app in Apps)
{
ListViewItem item = new ListViewItem(app);
APPView.Items.Add(item);
}
}
private void mainForm_Load(object sender, EventArgs e)
{
sInfo = new SystemUtils();
run();
List<Diskinfo> dInfo = sInfo.GetLogicalDrives();
for (int i = 0; i < dInfo.Count; i++)
{
ListViewItem item = new ListViewItem(dInfo[i].DiskName);
item.SubItems.Add(dInfo[i].Size.ToString());
item.SubItems.Add(dInfo[i].FreeSpace.ToString());
DiskView.Items.Add(item);
}
}
private void run()
{
tmrProcess_Tick(tmrProcess, new EventArgs()); //每隔一秒刷新
tmrSysInfo_Tick(tmrSysInfo, new EventArgs());
刷新_Click(刷新, new EventArgs());
}
// 结束进程
private void 结束_Click_1(object sender, EventArgs e)
{
if (ProcessView.SelectedItems.Count > 0) //光标选中某一项
{
ListViewItem item = ProcessView.SelectedItems[0];
int pid = int.Parse(item.Text); //通过PID来辨认选中的进程
string pName = item.SubItems[1].Text;
DialogResult dr = MessageBox.Show(string.Format("确定要结束进程 {0} 吗?", pName),
"警告", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
if (dr == DialogResult.OK)
{
SystemUtils.EndProcess(pid);
}
}
}
核心工具类:
public class SystemUtils
{
private int cpuCount = 0;//cpu个数
private PerformanceCounter cpuLoad;//CPU计数器
private long physicalMemory = 0; //物理内存
private const int GW_HWNDFIRST = 0;//返回的句柄标识了在Z序最高端的相同类型的窗口
private const int GW_HWNDNEXT = 2;//返回的句柄标识了在Z序中指定窗口下的相同类型的窗口
private const int GWL_STYLE = (-16); //获得窗口风格
private const int WS_VISIBLE = 268435456;
private const int WS_BORDER = 8388608;
#region 调用windows AIP声明(直接调用从 DLL 导出的函数。)
[DllImport("User32")]
private extern static int GetWindow(int hWnd, int wCmd); //返回与指定窗口有特定关系(如Z序或所有者)的窗口句柄。
[DllImport("User32")]
private extern static int GetWindowLongA(int hWnd, int wIndx);//该函数获得有关指定窗口的信息,函数也获得在额外窗口内存中指定偏移位地址的32位度整型值。
[DllImport("user32")]
private static extern bool GetWindowText(int hWnd, StringBuilder title, int maxBufSize); //将指定窗口的标题条文本(如果存在)拷贝到一个缓存区内
[DllImport("user32", CharSet = CharSet.Auto)]
private extern static int GetWindowTextLength(IntPtr hWnd); //返回指定窗口的标题文本(如果存在)的字符长度
#endregion
#region 构造器
public SystemUtils()
{
//初始化cpu计数器
cpuLoad = new PerformanceCounter("Processor","% Processor Time","_Total");
cpuLoad.MachineName = ".";
cpuLoad.NextValue();
//cpu个数
cpuCount = Environment.ProcessorCount;
//获取物理内存
ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mop in moc)
{
if (mop["TotalPhysicalMemory"]!= null)
{
physicalMemory = long.Parse(mop["TotalPhysicalMemory"].ToString());
}
}
}
#endregion
#region get方法
/// <summary>
/// 获取cpu数量
/// </summary>
public int CpuCount
{
get
{
return this.cpuCount;
}
}
/// <summary>
/// 获取cpu占用率
/// </summary>
public float CpuLoad
{
get
{
return this.cpuLoad.NextValue();
}
}
/// <summary>
/// 获取可用内存
/// </summary>
public long MemoryAvailable
{
get
{
long availablebytes = 0;
ManagementClass mos = new ManagementClass("Win32_OperatingSystem");
foreach (ManagementObject mo in mos.GetInstances())
{
if (mo["FreePhysicalMemory"] != null)
{
availablebytes=1024*long.Parse(mo["FreePhysicalMemory"].ToString();
}
}
return availablebytes;
}
}
/// <summary>
/// 获取物理内存
/// </summary>
public long PhysicalMemory
{
get
{
return this.physicalMemory;
}
}
#endregion
#region 获得分区信息
/// <summary>
/// 获取分区信息
/// </summary>
public List<Diskinfo> GetLogicalDrives()
{
List<Diskinfo> drives = new List<Diskinfo>();
ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk");
ManagementObjectCollection disks = diskClass.GetInstances();
foreach (ManagementObject disk in disks)
{
// DriveType.Fixed 为固定磁盘(硬盘)
if (int.Parse(disk["DriveType"].ToString()) == (int)DriveType.Fixed)
{
drives.Add(new Diskinfo(disk["Name"].ToString(), long.Parse(disk["Size"].ToString()), long.Parse(disk["FreeSpace"].ToString())));
}
}
return drives;
}
/// <summary>
/// 获取特定分区信息
/// </summary>
/// <param name="DriverID">盘符</param>
public List<Diskinfo> GetLogicalDrives(char DriverID)
{
List<Diskinfo> drives = new List<Diskinfo>();
WqlObjectQuery wmiquery = new WqlObjectQuery("SELECT * FROM Win32_LogicalDisk WHERE DeviceID = '" + DriverID + ":'");
ManagementObjectSearcher wmifind = new ManagementObjectSearcher(wmiquery);
foreach (ManagementObject disk in wmifind.Get())
{
if (int.Parse(disk["DriveType"].ToString()) == (int)DriveType.Fixed)
{
drives.Add(new Diskinfo(disk["Name"].ToString(), long.Parse(disk["Size"].ToString()), long.Parse(disk["FreeSpace"].ToString())));
}
}
return drives;
}
#endregion
#region 获取进程列表
public List<ProcessInfo> GetProcessInfo()
{
List<ProcessInfo> proInfo = new List<ProcessInfo>();
Process[] process = Process.GetProcesses(); //取得计算机所有的进程
foreach(Process instance in process) //以此建立进程信息
{
try
{
proInfo.Add(new ProcessInfo(instance.Id, instance.ProcessName,
instance.TotalProcessorTime.TotalMilliseconds,
instance.WorkingSet64,
instance.MainModule.FileName));
}
catch { }
}
return proInfo;
}
#endregion
#region 结束指定进程
public static void EndProcess(int pid)
{
try
{
Process pro = Process.GetProcessById(pid);
pro.Kill();
}
catch { }
}
#endregion
#region 查找所有应用程序标题
public static List<string> FindAllApps(int Handle)
{
List<string> Apps = new List<string>();
int hwCurr;
hwCurr = GetWindow(Handle, GW_HWNDFIRST);
while (hwCurr > 0)
{
int IsTask = (WS_VISIBLE | WS_BORDER);
int lngStyle = GetWindowLongA(hwCurr, GWL_STYLE);
bool TaskWindow = ((lngStyle & IsTask) == IsTask);
if (TaskWindow)
{
int length = GetWindowTextLength(new IntPtr(hwCurr));
StringBuilder sb = new StringBuilder(2 * length + 1);
GetWindowText(hwCurr, sb, sb.Capacity);
string strTitle = sb.ToString();
if (!string.IsNullOrEmpty(strTitle))
{
Apps.Add(strTitle);
}
}
hwCurr = GetWindow(hwCurr, GW_HWNDNEXT);
}
return Apps;
}
#endregion
}
5) 结果展示
五、结束语
通过此次课程设计,掌握了进程调度算法的原理以及windowsAPI的函数调用,同时练习了java语言和c#语言编程。
通过此次编程,我体会到了,编程不能急于求成,而应该首先认真分析设计要求,整理清楚设计过程中所需要用到的知识,明白了大体框架之后,在动手编程。遇到自己不知道的知识,应该主动上网查询或者去图书馆翻阅资料。
六、参考资料
[1] 汤小丹.计算机操作系统(第三版)[M].西安:西安电子科技大学出版社,2007.
[2] 柠檬隐士的博客: http://www.cnblogs.com/lemony/archive/2007/04/11/708309.html
[3] 百度文库
七、设计时间与安排
1、设计时间: 2周
2、设计时间安排:
熟悉实验设备、收集资料: 2 天
设计图纸、实验、计算、程序编写调试: 4 天
编写课程设计报告: 1 天
答辩: 1 天