操作系统第三版实验指导

合集下载

操作系统实验指导书

操作系统实验指导书

《操作系统》课程实验指导书一.实验总学时(课外学时/课内学时):4/8 总学分:8/44必开实验个数: 4 选开实验个数:0二.适用专业:网络工程、计算机科学与技术2007级三.考核方式及办法:在规定实验时间内完成实验要求,依据实验过程及实验结果在实验现场逐一检查考核。

四.配套的实验教材或指导书:自编实验指导书五. 实验项目:实验1 SHELL命令的使用1、实验目的通过对LINUX的系统启动、注销、关闭和关机,帐号管理,文件系统的日常管理,文件系统的权限控制等常用基本命令的使用及与Windows下DOS SHELL的比较,了解现代操作系统SHELL的特点和功能。

了解编辑器vi的使用方法。

2、实验工具及环境LINUX系统网络环境或单机,Windows系统网络环境或单机。

3、实验计划学时2学时上机实际操作。

4、实验内容及操作步骤⑴系统启动和关闭①使用自己的账户登录UNIX系统,查看系统提示符确定自己使用的shell程序类型别。

◎开机后,系统自检启动后提示login:(输入:root↙)password:(输入:用户口令↙,root用户为redhat)◎查看/etc/passwd文件可以获得用户使用的shell#grep $LOGNAME /etc/passwd↙可能的显示为:user001:*:200:50::/usr/user001:/bin/sh请思考上述命令怎样得到了当前使用的shell类型的?使用下面的命令也可以查看当前shell:#echo $SHELL②注销和关机命令。

◎用户注销使用:$exit↙或$<ctrl>+<D>↙或$logout↙◎超级用户关机使用:#shutdown↙该命令将结束所有的进程,当执行此命令后系统提示“Safe to Power off or Press Any Keyto Reboot”时可以关闭电源或按任一键重启系统。

◎haltsys(halt),reboot只能由超级用户在单用户模式下使用。

操作系统实验指导

操作系统实验指导

计算机专业《操作系统》实验指导书网络和信息安全教研室计算机专业《操作系统》实验指导书实验一 Linux系统的安装一、实验目的1、深入认识磁盘分区2、掌握Linux安装的基本过程3、掌握多系统共存的系统安装方法二、实验任务在现有系统安装Redhat Linux系统,注意不要破坏现有系统。

三、实验指导参考《Linux上机实践教程》第一章内容。

实验二 Linux系统的基本使用一、实验目的1、熟悉linux系统的启动、登入和退出2、熟悉linux系统文件和目录的基本使用3、熟悉其它常用命令及虚拟终端的使用4、体会linux系统作为分时系统的特点二、实验任务启动、登入和退出linux系统练习使用文件和目录操作的基本命令使用它常用命令及虚拟终端练习使用Vi编辑器三、实验指导参考《Linux上机实践教程》第二、三章内容。

实验三 windows 2000中进程的创建和控制一、实验目的1、加深对进程概念的理解,明确进程和程序的区别2、进一步认识进程并发执行的实质3、掌握windows 2000中进程创建和控制的编程方法二、实验任务创建一个windows窗口程序,含有4个菜单项,分别用来创建和撤消记事本进程和计算器进程。

若相应进程已经创建了,再选择创建进程菜单,则弹出对话框提示进程已经创建;若进程已经撤消了,再选择撤消进程菜单,则弹出对话框提示进程已经撤消。

注意考虑从主程序外部启动和关闭进程的情况。

三、实验指导1、Win32的进程的概念进程是应用程序的运行实例,由私有虚拟地址空间、代码、数据和其他操作系统资源(如进程创建的文件、管道、同步对象等)组成。

一个应用程序可以有一个或多个进程,一个进程可以有一个或多个线程,其中一个是主线程。

进程要完成什么事情的话必须至少拥有一个线程,由线程来负责执行包含在地址空间的代码。

2、Win32的进程的创建Windows所创建的每个进程都从调用CreateProcess() API函数开始,该函数的任务是在对象管理器子系统内初始化进程对象。

操作系统实验指导书3rd

操作系统实验指导书3rd

版本号:3.0撰写人:孙自广合作者:陈波(博士)欧阳浩日期:2011-09-08操作系统实验指导书(第3版)广西工学院计算机工程系2011年09月前言操作系统是计算机科学与技术专业(软件工程方向)的一门非常重要的专业课程,操作系统是应用软件与底层硬件的桥梁。

通俗的说“只有搞懂了操作系统,才能真正理解计算机”。

学好操作系统课程可以提升学生应用计算机解决问题的能力,并获得开发大型复杂软件的经验。

操作系统至关重要,但学好它并不容易。

虽然Windows界面友好,方便使用,但是底层运行机制被有效的隐藏,在很多人眼里计算机还是一个黑匣子。

在选择教学用操作系统上颇费苦心,目前可用于教学的操作系统有Minix, Nochos, Geekos, JOS,FreeBSD等,而Linux不仅是开源的,而且资料丰富并拥有大量的应用软件,所有我们选择了Linux作为实验的平台。

本实验指导书参阅了很多网上的优秀资源,在此对提供这些资源的作者,表示感谢。

目录前言 (1)实验1 Linux的安装与使用 (3)实验2 Linux的键盘命令 (4)实验3-1 Linux进程的创建与父子进程同步 (8)实验3-2 Linux子进程映像的重新加载 (10)实验4-1 Linux软中断通信 (11)实验4-2 Linux管道通信 (13)实验4-3 Linux信息缓冲通信 (14)实验4-4 Linux共享存储通信 (16)实验5 Linux 信号量与P、V操作函数的定义 (18)实验6 在Linux中增加一个新的系统调用函数 (20)实验7 动态申请内存 (21)实验8 Linux字符设备驱动 (22)实验9 Linux 文件系统调用 (23)1.实验目的在做本课程系列实验之前需要先安装Linux系统。

如果你的计算机上已经安装了Linux,则本实验可以不做。

熟悉Linux提供的图形用户界面。

2. 实验预备知识Linux系统的安装方法和图形界面基本操作请参考相关资料。

操作系统实验指导书

操作系统实验指导书

操作系统实验指导书实验⼀操作系统⽤户接⼝实验⼀、实验⽬的熟悉操作系统的命令接⼝、图形⽤户接⼝和程序接⼝。

⼆、实验内容:1、使⽤操作系统的命令接⼝。

使⽤Windows常⽤命令:dir 、md、copy、date、help,显⽰这些命令的结果,并解释这些命令的作⽤。

图1-1 命令控制台图1-2 windows常⽤命令图1-3 windows常⽤命令图1-4 windows常⽤命令使⽤图1-5 windows常⽤命令使⽤2、使⽤操作系统的程序接⼝。

VB环境下:编制⼀⼩程序,使其可通过某个系统调⽤来获得os 提供的某种服务,如打开控制⾯板:Shell "rundll32.exe Shell32.dll,Control_RunDLL", 1VC环境下:⽤C语⾔编制⼀个⼩程序,使其可通过Localtime( )系统调⽤来获得OS提供的时间和⽇期。

3、使⽤操作系统的图形⽤户接⼝(略)。

三、思考:OS向⽤户提供的命令接⼝、图形⽤户接⼝和程序接⼝分别适⽤于哪些场合?实验⼆进程创建与撤消⼀、实验⽬的1、加深对进程概念的理解和进程创建与撤消算法;2、进⼀步认识并发执⾏的实质。

⼆、实验内容本实验完成如下三个层次的任务:(1)系统级—以普通⽤户⾝份认识windows的进程管理。

通过windows的“任务管理器”观察进程的状态,进⾏进程的创建、切换和撤销。

(2)语⾔级—以普通程序员⾝份认识⾼级语⾔VC++/Java/VB的进程创建与撤销⼯具。

(3)模拟级—以OS设计师⾝份编程模拟实现进程创建与撤销功能,并在屏幕上观察进程活动的结果。

三、实验步骤1、windows的进程管理当前状态图2-1 windows任务管理器切换前图2-2 windows任务管理器切换后图2-3 windows任务管理器撤销图2-4 windows任务管理器2、VC++进程创建与撤销⼯具Windows所创建的每个进程都从调⽤CreateProcess() API函数开始,该函数的任务是在对象管理器⼦系统内初始化进程对象。

存储管理算法实验报告-计算机操作系统教程(第三版)

存储管理算法实验报告-计算机操作系统教程(第三版)

存储器管理(一)一、实验目的模拟分页式虚拟存储管理中硬件的地址转换和缺页中断,以及选择页面调度算法处理缺页中断。

二、实验目的在计算机系统中,为了提高主存利用率,往往把辅助存储器(如磁盘)作为主存储器的扩充,使多道运行的作业的全部逻辑地址空间总和可以超出主存的绝对地址空间。

用这种办法扩充的主存储器称为虚拟存储器。

通过本实验帮助同学理解在分页式存储管理中怎样实现虚拟存储器。

三、实验题目示例程序给出了模拟分页式存储管理中硬件的地址转换和产生缺页中断;请写出用先进先出(FIFO)页面调度算法处理缺页中断或用最近最少用(LRU)页面调度算法处理缺页中断的程序。

四、示例程序源代码#include "stdio.h"#define blockLength 128typedef enum {NO=0,YES}FLAG;typedef struct pagetable {int pageNumber;FLAG flag;int memoryBlock;int place;}PAGETAB;typedef struct job{int pageNumber;int unitNumber;}JOB;PAGETAB pageTAB[7]={0,YES,5,11,1,YES,8,12,2,YES,9,13,3,YES,1,21,4,NO,-1,22,5,NO,-1,23,6,NO,-1,121};JOB work[12] = {0,70,1,50,2,15,3,21,0,56,6,40,4,53,5,23,1,37,2,78,4,1,6,84};int main(int argc, char* argv[]){//first init page table// and work list// look for the work list and pick one to fix the page tablefor(int i=0; i<12;i++){printf("Instruction sequence :%d\n",i+1);int j = work[i].pageNumber;printf("The page %d is in the memory? %s!\n",j,(pageTAB[j].flag == YES)?"YES":"NO");if(pageTAB[j].flag == YES){int absoluteAddress = pageTAB[j].memoryBlock*blockLength+work[i].unitNumber; printf("Instruction absolute address:%d\n",absoluteAddress);}else{printf("missing page interrupt, page fault interrupt!\n");}}return 0;}存储器管理(二)一、实验目的:掌握分页式存储管理的基本概念和实现方法。

OS操作系统课程实验指导书附运行截图

OS操作系统课程实验指导书附运行截图

OS操作系统课程实验指导书附运行截图实验1使用动态优先权的进程调度算法的模拟1、实验目的(1)加深对进程概念的理解(2)深入了解系统如何组织进程,创建进程(3)进一步认识如何实现处理机调度2、实验内容(1)实现对N个进程采用动态优先权优先算法的进程调度。

(2)每个用来标识进程的进程控制块PCB用结构来描述,包括以下字段:进程标识数ID。

进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。

进程已占用的CPU时间CPUTIME。

进程还需占用的CPU时间ALLTIME。

当进程运行完毕时,ALLTIME变为0。

进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK 个时间片后,将进入阻塞状态。

进程被阻塞的时间BLOCKTIME,表示已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。

进程状态STATE。

队列指针NEXT,用来将PCB排成队列。

(3)优先数改变的原则:进程在就绪队列中停留一个时间片,优先数加1。

进程每运行一个时间片,优先数减3。

(4)假设在调度前,系统中有5个进程,它们的初始状态如下:ID 0 1 2 3 4PRIORITY 9 38 30 29 0CPUTIME 0 0 0 0 0ALLTIME 3 3 6 3 4STARTBLOCK 2 -1 -1 -1 -1BLOCKTIME 3 0 0 0 0STATE ready ready ready ready ready(5)为了清楚的观察各进程的调度过程,程序应将每个时间片内的情况显示出来,参照的具体格式如下:RUNNING PROG:i READY-QUEUE:->id1->id2BLOCK-QUEUE:->id3->id4= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = == = =ID 0 1 2 3 4PRIORITY P0 P1 P2 P3 P4CUPTIME C0 C1 C2 C3 C4ALLTIME A0 A1 A2 A3 A4STARTBLOCK T0 T1 T2 T3 T4BLOCKTIME B0 B1 B2 B3 B4STATE S0 S1 S2 S3 S43、实验结果(给出编写的程序源代码和运行结果的截图)【程序代码】#include#include#define N 5// 进程状态enum STATE { Ready, Run, Block, Finish };// PCB数据结构struct PCB {int id; // 标志数int priority; // 优先数int cpuTime; // 已占CPU时间int allTime; // 还需占CPU时间int blockTime; // 已被阻塞的时间int startBlock; // 开始阻塞时间STATE state; // 进程状态PCB *pre; // PCB的前指针PCB *nxt; // PCB的后指针};int id[N] = {0, 1, 2, 3, 4};int priority[N] = {9, 38, 30, 29, 0};int cpuTime[N] = {0, 0, 0, 0, 0};int allTime[N] = {3, 3, 6, 3, 4};int startBlock[N] = {2, -1, -1, -1, -1};int blockTime[N] = {3, 0, 0, 0, 0};void QuePush(PCB *process, PCB *queHead){process->pre = NULL;process->nxt = queHead->nxt;if (queHead->nxt != NULL) {queHead->nxt->pre = process;}queHead->nxt = process;}void quePop(PCB *process, PCB *queHead){if (process->pre != NULL) {process->pre->nxt = process->nxt;} else {queHead->nxt = process->nxt;}if (process->nxt != NULL) {process->nxt->pre = process->pre;}process->pre = process->nxt = NULL;}void queWalk(PCB *queHead){PCB *pro = queHead->nxt;if (pro == NULL) {printf("(没有进程啦)\");return;}while (pro != NULL){printf("id: %d, priority: %d, cpuTime: %d, alltime: %d,blockTime: %d,state:%d,startblock: %d\", pro->id, pro->priority, pro->cpuTime, pro->allTime, pro->blockTime, pro->state, pro->startBlock);pro = pro->nxt;}}int readyQueNum; // 就绪队列的进程数量PCB readyQueHead; // 就绪队列的头部PCB *readyMaxProcess; // 就绪队列中优先级最高的进程void readyQuePush(PCB *process){readyQueNum ++;process->state = Ready;QuePush(process, &readyQueHead);}PCB* readyQuePop(){readyQueNum --;quePop(readyMaxProcess, &readyQueHead);return readyMaxProcess;}// 每个时间片,更新就绪队列里进程的信息void readyQueUpdate(){int maxPriority = -1;PCB *pro = readyQueHead.nxt;if (pro == NULL) {// 就绪队列没有进程readyMaxProcess = NULL;return;}while (pro != NULL){pro->priority ++;if (pro->priority > maxPriority) {maxPriority = pro->priority;readyMaxProcess = pro;}pro = pro->nxt;}}// 返回就绪队列最高优先级的值int readyMaxPriority(){return readyMaxProcess->priority;}// 查看就绪队列里进程的信息void readyQueWalk(){printf("就绪队列里的进程信息为:\");queWalk(&readyQueHead);}#define EndBlockTime 3 // 进程最长被阻塞时间int blockQueNum; // 阻塞队列的进程数量PCB blockQueHead; // 阻塞队列的头部PCB *blockMaxProcess; // 阻塞队列中优先级最高的进程// 进程插入到阻塞队列void blockQuePush(PCB *process){blockQueNum ++;process->blockTime = 0;process->state = Block;if (process->blockTime != -1) {QuePush(process, &blockQueHead);}}// 优先级最高的进程出列PCB* blockQuePop(){blockQueNum --;quePop(blockMaxProcess, &blockQueHead);return blockMaxProcess;}// 每个时间片,更新阻塞队列里进程的信息void blockQueUpdate(){int maxPriority = -1;PCB *pro = blockQueHead.nxt;while (pro != NULL){pro->blockTime ++;if (pro->blockTime >= EndBlockTime) {PCB *process = pro;pro = pro->nxt;// 阻塞时间到,调入就绪队列blockQueNum --;quePop(process, &blockQueHead); readyQuePush(process);} else if (pro->priority > maxPriority) {// 更新阻塞队列里优先级最高的进程指针maxPriority = pro->priority; blockMaxProcess = pro;pro = pro->nxt;}}}// 查看阻塞队列里进程的信息void blockQueWalk(){printf("阻塞队列里的进程信息为:\"); queWalk(&blockQueHead);}// 初始化数据void initData(){// 初始化就绪队列和阻塞队列readyQueNum = blockQueNum = 0; readyMaxProcess = blockMaxProcess = NULL;readyQueHead.pre = readyQueHead.nxt = NULL; blockQueHead.pre = blockQueHead.nxt = NULL; // 初始化进程进入就绪队列int i, maxPriority = -1;for (i = 0; i < N; i ++){// 分配一个PCB的内存空间PCB *pro = (PCB *)malloc(sizeof(PCB));// 给当前的PCB赋值pro->id = id[i];pro->priority = priority[i];pro->cpuTime = cpuTime[i];pro->allTime = allTime[i];pro->blockTime = blockTime[i];pro->startBlock = startBlock[i];if (pro->allTime > 0) {// 插入到就绪队列中readyQuePush(pro);// 更新就绪队列优先级最高的进程指针if (pro->priority > maxPriority) {maxPriority = pro->priority; readyMaxProcess = pro;}}}}// 模拟cpu执行1个时间片的操作void cpuWord(PCB *cpuProcess){cpuProcess->priority -= 3;if (cpuProcess->priority < 0) {cpuProcess->priority = 0;}cpuProcess->cpuTime ++;cpuProcess->allTime --;// 显示正执行进程的信息:printf("CPU正执行的进程信息为:\");printf("id: %d, pri: %d, alltime: %d\", cpuProcess->id,cpuProcess->priority, cpuProcess->allTime);}int main(){int timeSlice = 0; // 模拟时间片int cpuBusy = 0; // 模拟cpu状态PCB *cpuProcess = NULL; // 当前在cpu执行的进程initData(); // 初始化// 模拟进程调度while (1){if (readyQueNum == 0 && blockQueNum == 0 && cpuBusy == 0) { // 就绪队列、阻塞队列和cpu无进程,退出break;}if (cpuBusy == 0) {// cpu空闲,选择一个进程进入cpuif (readyQueNum > 0) {// 选择绪队列优先级最高的进程cpuProcess = readyQuePop();} else {// 就绪队列没有进程,改为选择阻塞队列优先级最高的进程cpuProcess = blockQuePop();}cpuProcess->cpuTime = 0;cpuProcess->state = Run;cpuBusy = 1;cpuProcess->startBlock --;}timeSlice ++;printf("\第%d个时间片后:\", timeSlice);// 模拟cpu执行1个时间片的操作cpuWord(cpuProcess);if (cpuProcess->allTime == 0) {cpuProcess->state = Finish;// 释放已完成进程的PCBfree(cpuProcess);cpuBusy = 0;}// 更新就绪队列和阻塞队列里的进程信息blockQueUpdate();readyQueUpdate();// 查看就绪队列和阻塞队列的进程信息readyQueWalk();blockQueWalk();if ((cpuProcess -> startBlock) > 0) {blockQuePush(cpuProcess);cpuProcess = readyQuePop();}else {if (cpuBusy == 1 && readyQueNum > 0 && cpuProcess->priority < readyMaxPriority()){readyQuePush(cpuProcess);cpuProcess = readyQuePop();}}}printf("\模拟进程调度算法结束2145115 刘成路\");return 0;}【运行截图】实验2使用动态分区分配方式的模拟1、实验目的(1)了解动态分区分配方式中使用的数据结构和分配算法(2)加深对动态分区存储管理方式及其实现过程的理解。

proteus教学实验系统(单片机e型)实验指导

proteus教学实验系统(单片机e型)实验指导

目录(版本 1.03)第1章PROTEUS教学实验系统(单片机E型)简介及使用说明 (1)1.1 系统简介 (1)1.2 实验系统的硬件布局 (4)1.3 实验系统原理图 (5)1.4 实验板硬件图 (16)1.5 USB下载方式说明 (23)第2章硬件实验目录 (27)实验一I /O口输出实验—LED流水灯实验 (27)实验二I/O口输入/输出实验—模拟开关灯 (29)实验三8255并行I/O扩展实验 (31)实验四无译码的七段数码管显示实验 (33)实验五BCD译码的多位数码管扫描显示实验 (36)实验六独立式键盘实验 (38)实验七计数器实验 (40)实验八定时器实验 (42)实验九单个外部中断实验 (44)实验十中断嵌套实验 (46)实验十一矩阵键盘扫描实验 (49)实验十二串行端口并行输出扩充实验 (51)实验十三串行端口并行输入扩充实验 (53)实验十四单片机与PC之间串行通信实验 (55)实验十五双单片机通信实验 (58)实验十六I2C总线——AT24CXX存储器读写 (60)实验十七温度传感器DS18B20实验 (64)实验十八实时时钟DS1302实验 (66)实验十九A/D转换实验 (68)实验二十D/A转换实验 (70)实验二十一1602液晶显示的控制(44780) (72)实验二十二12864液晶显示的控制(KS0108) (74)实验二十三直流电机控制实验 (76)实验二十四步进电机控制实验 (78)实验二十五16X16阵列LED显示 (81)实验二十六直流电机测速实验 (83)实验二十七串行AD—TLC549实验 (85)实验二十八串行DA—TLC5615实验 (87)实验二十九继电器控制实验 (89)实验三十LCD 1602 IO方式驱动 (92)第3章软件仿真实验目录 (96)实验一可控硅驱动 (96)实验二光耦应用实验 (98)实验三单片机播放音乐实验 (100)实验四SD卡读写实验 (104)第1章PROTEUS教学实验系统(单片机E型)简介及使用说明1.1 系统简介【硬件特点】PROTEUS教学实验系统(单片机E型)是我公司陆续推出的PROTEUS教学实验系统第三版。

操作系统实验指导书

操作系统实验指导书

操作系统实验指导书一、实验说明1、实验目的实验是操作系统原理课程中不可缺少的重要教学环节,实验目的是使学生理论联系实际,使学生在实践探索中去发现问题、去解决问题,提高了学生获取知识和应用技术的能力,培养了学生分析和解决问题的能力。

《操作系统原理》要求理论与实践相结合,本门实验课程是对《操作系统原理》课堂教学的一个重要补充,与理论学习起着相辅相成的作用,是实施《操作系统原理》教学的一个重要组成部分。

通过本实验课的实践学习,可以增强本专业的学生对系统实现的认识。

对加深理解和掌握操作系统相关原理有重要帮助。

2、实验要求进一步了解和掌握操作系统原理,提高系统设计的能力。

对每一实验题目,应独立完成,并要求:·上机前,学生必须做好充分的实验准备工作,掌握与实验相关的背景知识,用任一种高级语言编写程序。

·上机时,认真调试,并观察、记录程序运行过程中出现的现象和问题。

·上机后,分析实验结果并写出实验报告。

3、实验报告要求每个实验(包括选做的)均应编写实验报告,学生实验后要写出严谨的、实事求是的、文字通顺的、字迹公整的实验报告。

实验报告应包括以下内容:(1)实验题目(2)实验目的(3)实验内容●程序中使用的数据结构及符号说明●流程图●源程序清单并附上注释(4)实验结果及分析●运行结果(必须是上面程序清单所对应输出的结果)●对运行情况所作的分析以及本次调试程序所取得的经验。

如果程序未能通过,应分析其原因。

二、实验内容实验一熟悉使用计算机系统一、实验名称:熟悉使用计算机系统二、实验目的与要求通过对Windows操作系统的使用,熟悉Windows操作系统中的基本概念,如单用户、多任务、进程和文件等,熟悉Windows中命令行方式下常用命令的使用方法;进一步熟悉TC语言与开发环境,为以后的实验打好基础。

三、实验内容1.开机后,熟悉Windows的界面(桌面、任务栏、开始按钮<点击后出现“开始”菜单>、我的电脑图标、回收站、我的文档)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验一命令解释程序1.1 实验目的•掌握命令解释程序的设计方法。

•学习Windows系统调用的使用,了解目录操作、进程控制等相关知识。

•理解并发程序中的同步问题。

•培养C/C++语言程序设计技能,提高程序设计和文档编写能力。

•锻炼团队成员的交流与合作能力。

1.2 实验要求1.2.1基本要求本实验要求实现一个简单的命令解释程序,其设计类似于MS-DOS的Command程序,程序应当具有如下一些重要特征:•能够执行cd、dir、tasklist、taskkill、history、exit等内部命令。

•能够创建前台进程和后台进程。

此外,还应做到:•使用VC建立工程。

•提供清晰、详细的设计文档和解决方案。

本实验的具体要求如下:(1)参考Command命令解释程序,采用控制台命令行输入,命令提示行是当前目录与提示符“>”,在提示符后输入命令,执行结果在控制台中显示,如图1-1所示。

(2)实现以下内部命令。

•cd <路径> 切换目录。

•dir 显示指定目录下的文件、目录及磁盘空间等相关信息。

•tasklist 显示系统当前进程信息,包括进程标识符pid、线程数、进程名等。

•taskkill <pid> 结束系统中正在运行的进程,须提供进程标识pid。

•history 显示控制台中曾经输入过的命令。

•exit 退出控制台。

(3)对前台进程和后台进程的操作。

本实验设计的命令解释程序可以将进程放在前台执行或者后台执行。

图1-1 命令解释器界面启动前台进程,即在提示符下输入:fp <可执行文件>启动后台进程的命令格式为:bg <可执行文件>解释程序在前台进程运行期间需要一直等待,直到前台进程运行结束才打印命令提示符,而在后台进程运行期间不必等待,会立刻打印出命令提示符,允许用户输入下一条命令。

命令解释程序中还需要捕获Ctrl+C组合键的信号来结束前台正在运行的进程,并返回用户输入界面,等待新命令输入。

(4)其他要求。

该命令解释程序应该具有相应的出错提示功能。

程序每次接收用户输入的一行命令,在用户按下回车键(Enter)后开始执行命令。

空命令只打印一个新的提示行,不做其他处理。

定义空格为分隔符,程序应能处理命令行中出现的重复空格符。

提供帮助命令help,供使用者查询每个命令的用法。

1.2.2 进一步要求(1)实现管道命令。

命令格式为:<命令> {| <命令>}管道命令的作用是将管道分隔符| 前一个命令的输出作为后一个命令的输入。

(2)仿照MS-DOS Command命令解释程序对现有命令语法进行改进,实现命令参数处理功能。

例如dir命令,附加/A(显示具有指定属性的文件),附加/B(使用空格式),附加/C(在文件大小中显示千位数分隔符)等参数。

如dir /A。

(3)实现进程的前台/后台切换命令,这需要查阅相关Windows API来解决。

1.2.3 实验步骤建议(1)熟悉Windows相关API函数的调用。

(2)编写小程序练习使用这些系统调用。

(3)编写命令解释器设计文档。

(4)按照设计文档编写代码。

(5)不断完善程序细节。

(6)测试。

(7)写实验报告(包括需求、设计、测试和使用说明等内容,格式可参考1.6节源程序与运行结果之“实验报告模板”)。

1.3 相关基础知识1.3.1 命令解释程序与内核的关系命令解释程序是用户和系统内核之间的接口程序。

对于Windows系统来说,由于已经提供了具有良好交互性的图形用户界面,传统的控制台命令解释程序已经很少被广大用户所了解和使用了。

但是,对于某些应用,例如删除所有扩展名为tmp的文件,或是删除某些具有特殊名字的病毒文件,在图形用户界面下很难甚至不能完成,这时需要通过Windows提供的Command命令接口来完成。

Command程序是一个命令语言解释器,它拥有自己内建的命令集,用户或其他应用程序都可通过对Command程序的调用完成与系统内核的交互。

我们可以把系统内核想象成一个球体的中心,Command命令解释程序就是包围内核的外壳,如图1-2所示。

图1-2 硬件、内核、系统调用以及Command之间的层次关系1.3.2 系统调用应用程序是以函数调用的方式来通知操作系统执行相应的内核功能。

操作系统所能够完成的每一个特殊功能通常都有一个函数与其对应,即操作系统把它所能够完成的功能以函数的形式提供给应用程序使用。

应用程序对这些函数的调用叫做系统调用,这些函数的集合就是Windows操作系统提供给应用程序编程的接口(Application Programming Interface),简称Windows API或Win32 API(注:某些Win32 API,如管理Windows 线程的API等,它们并没有操纵内核对象,因此不是系统调用。

本实验只讨论API的使用,不再做进一步区分)。

所有在Win32平台上运行的应用程序都可以调用这些函数。

使用Windows API,应用程序可以充分挖掘Windows的32位操作系统的潜力。

Microsoft的所有32位平台都支持统一的API,包括函数、结构、消息、宏及接口。

使用Windows API不但可以开发出在各种Windows平台上都能运行的应用程序,而且也可以充分利用每个平台特有的功能和属性。

Windows的相关API都可以在MSDN中查到,包括定义、使用方法等。

下面简单介绍本次实验中所涉及的Windows API。

1.GetCurrentDirectory函数功能说明查找当前进程的当前目录,调用成功返回装载到lpBuffer的字节数。

格式DWORD GetCurrentDirectory(DWORD nBufferLength,LPTSTR lpBuffer)参数说明nBufferLength:缓冲区的长度。

lpBuffer:指定一个预定义字串,用于装载当前目录。

2.WaitForSingleObject函数功能说明等待一个事件信号直至该信号出现或是超时。

若有信号则返回WAIT_OBJECT_0,若等待超过dwMilliseconds时间还是无信号则返回WAIT_TIMEOUT。

格式DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds)参数说明hHandle:事件的句柄。

dwMilliseconds:最大等待时间,以ms计时。

3.SetCurrentDirectory功能说明设置当前目录,非0表示成功,0表示失败。

格式BOOL SetCurrentDirectory(LPCTSTR lpPathName)参数说明lpPathName:新设置的当前目录的路径。

4.FindFirstFile函数功能说明该函数用于到一个文件夹(包括子文件夹)中搜索指定文件,由这个函数返回的句柄可以作为一个参数用于FindNextFile函数。

这样一来,就可以方便地枚举出与lpFileName参数指定的文件名相符的所有文件。

格式HANDLE FindFirstFile(LPCTSTR lpFileName,LPWIN32_FIND_DATA lpFindFileData)参数说明lpFileName:文件名字符串。

lpFindFileData:指向一个用于保存文件信息的结构体。

5.FindNextFile函数功能说明继续查找FindFirstFile函数搜索后的文件。

由这个函数返回的句柄可以作为一个参数用于FindNextFile()函数。

这样一来,就可以方便地枚举出与lpFileName参数指定的文件名相符的所有文件。

格式BOOL FindNextFile(HANDLE hFindFile,LPWIN32_FIND_DATA lpFindFileData)参数说明hFindFile:前一个搜索到的文件的句柄。

lpFindFileData:指向一个用于保存文件信息的结构体。

6.GetVolumeInformation函数功能说明用于获取磁盘相关信息。

格式BOOL GetVolumeInformation(LPCTSTR lpRootPathName,LPTSTR lpVolumeNameBuffer,DWORD nVolumeNameSize,LPDWORD lpVolumeSerialNumber,LPDWORD lpMaximumComponentLength,LPDWORD lpFileSystemFlags,LPTSTR lpFileSystemNameBuffer,DWORD nFileSystemNameSize)参数说明lpRootPathName:磁盘驱动器代码字符串。

lpVolumeNameBuffer:磁盘驱动器卷标名称。

nVolumeNameSize:磁盘驱动器卷标名称长度。

lpVolumeSerialNumber:磁盘驱动器卷标序列号。

lpMaximumComponentLength:系统允许的最大文件长度。

lpFileSystemFlags:文件系统标识。

lpFileSystemNameBuffer:文件系统名称。

nFileSystemNameSize:文件系统名称长度。

7.GetDiskFreeSpaceEx函数功能说明获取与一个磁盘的组织以及剩余空间容量有关的信息。

格式BOOL GetDiskFreeSpaceEx(LPCTSTR lpRootPathName,PULARGE_INTEGER lpFreeBytesAvailableToCaller,PULARGE_INTEGER lpTotalNumberOfBytes,PULARGE_INTEGER lpTotalNumberOfFreeBytes,)参数说明lpRootPathName:不包括卷名的磁盘根路径名。

lpFreeBytesAvailableToCaller:调用者可用的字节数量。

lpT otalNumberOfBytes:磁盘上的总字节数。

lpT otalNumberOfFreeBytes:磁盘上可用的字节数。

8.FileTimeToLocalFileTime函数功能说明将一个FILETIME结构转换成本地时间。

格式BOOL FileTimeToLocalFileTime(const FILETIME* lpFileTime,LPFILETIME lpLocalFileTime)参数说明lpFileTime:包含了UTC时间信息的一个结构。

lpLocalFileTime:用于装载转换过的本地时间的结构体。

9.FileTimeToSystemTime函数功能说明根据一个FILETIME结构的内容,装载一个SYSTEMTIME结构。

相关文档
最新文档