2016西安交通大学操作系统实验报告
操作系统实验报告
实验二进程管理(二)进程的控制实验思考题:1.可执行文件加载时进行了哪些处理?解:可执行文件加载时首先是创建一个新进程的fork系统调用,然后用于实现进程自我终止的exit系统调用;改变进程原有代码的exec系统调用;用于将调用进程挂起并等待子进程终止的wait系统调用;获得进程标识符的getpid系统调用等处理过程。
2.什么是进程同步?wait(0)是如何实现进程同步的?解:进程同步是指对多个相关进程在执行次序上进行协调,以使并发执行的主进程之间有效地共享资源和相互合作,从而使程序的执行具有可在现行。
首先程序在调用fork()机那里了一个子进程后,马上调用wait(),使父进程在子进程调用之前一直处于睡眠状态,这样就使子进程先运行,子进程运行exec()装入命令后,然后调用wait(0),使子进程和父进程并发执行,实现进程同步。
实验三进程间的通信(一)信号机制实验一.参考程序#include<stdio.h>#include<signal.h>#include<unistd.h>Void waiting(),stop();Intwait_mark;Main(){Int P1,P2,stdout;While((P1=fork())==-1); /*创建子进程P1*/If(P1>0){While((p2=fork())==-1); /*创建子进程P2*/If(P2>0){Wait_mark=1;Signal(SIGINT,stop); /*接收到^C信号,转stop*/ Waiting();Kill(P1,16); /*向P1发软中断信号16*/Kill(P2,17); /*向P2发软中断信号17*/Wait(0); /*同步*/Wait(0);Printf(“Parent process is killed!\n”);Exit(0);}Else{Wait_mark=1;Signal(17,stop); /*接收到软中断信号17,转stop*/ Waiting();Lockf(stdout,1,0);Printf(“Child process 2 is killed by parent!\n);Lockf(stdout,0,0);Exit(0);}}Else{Wait_mark=1;Signal(16,stop); /*接收到软中断信号16,转stop*/ Waiting();Lockf(stdout,1,0);Printf(“Child process 1 is killed by parent!\n”);Lockf(stdout,0,0);Exit(0);}}Void waiting(){While(wait_mark!=0);}Void stop(){Wait_mark=0;}二.思考:1.该程序段前面部分用了两个wait(0),他们起什么作用?解:用了两个wait(0)的作用是同时使两个子进程P1和P2发出软中断信号,而不用等待。
操作系统实验报告
实验二进程调度1.目的和要求通过这次实验,理解进程调度的过程,进一步掌握进程状态的转变、进程调度的策略,进一步体会多道程序并发执行的特点,并分析具体的调度算法的特点,掌握对系统性能的评价方法。
2.实验内容阅读教材《计算机操作系统》第二章和第三章,掌握进程管理及调度相关概念和原理。
编写程序模拟实现进程的轮转法调度过程,模拟程序只对PCB进行相应的调度模拟操作,不需要实际程序。
假设初始状态为:有n个进程处于就绪状态,有m个进程处于阻塞状态。
采用轮转法进程调度算法进行调度(调度过程中,假设处于执行状态的进程不会阻塞),且每过t个时间片系统释放资源,唤醒处于阻塞队列队首的进程。
程序要求如下:1)输出系统中进程的调度次序;2)计算CPU利用率。
3.实验环境Windows操作系统、VC++6.0C语言4设计思想:(1)程序中进程可用PCB表示,其类型描述如下:struct PCB_type{int pid ; //进程名int state ; //进程状态2——表示“执行”状态1——表示“就绪”状态0——表示“阻塞”状态int cpu_time ; //运行需要的CPU时间(需运行的时间片个数)}用PCB来模拟进程;(2)设置两个队列,将处于“就绪”状态的进程PCB挂在队列ready中;将处于“阻塞”状态的进程PCB挂在队列blocked中。
队列类型描述如下:struct QueueNode{struct PCB_type PCB;Struct QueueNode *next;}并设全程量:struct QueueNode *ready_head=NULL,//ready队列队首指针*ready_tail=NULL , //ready队列队尾指针*blocked_head=NULL,//blocked队列队首指针*blocked_tail=NULL; //blocked队列队尾指针(3)设计子程序:start_state();读入假设的数据,设置系统初始状态,即初始化就绪队列和阻塞队列。
操作系统实验报告(2)
计算机实验报告(2)操作系统部分一、基本要求和内容1.了解操作系统的基本功能.2.认识WINDOWS桌面的各部分组成,掌握基本的桌面操作.3.掌握各种基本操作对象的操作方法.4.学会使用WINDOWS帮助.5.了解基本的DOS命令和基本的命令行操作方法.6.熟练掌握文件操作方法.7.掌握对图标的操作方法(移动/拖曳/单击/双击/右击等等).8.熟悉资源管理器窗口和”我的电脑”(“计算机”)窗口.9.掌握启动控制面板的方法,了解控制面板的主要功能,掌握使用控制面板对软硬件进行设置的方法。
10.掌握“运行”对话框的使用方法。
11.了解“任务管理器”的简单使用方法。
12.熟悉“画图”“记事本”“计算器”“写字板”等常用应用程序。
13.开始POWERPOINT的基本使用.二、通过上机实验解决下列问题1. CTRL+ALT+DEL 组合键的功能是:打开【任务管理器】窗口2.全角和半角的区别是:半角是一个字符,全角是两个字符3. CTRL+A组合键的功能是:全部选中CTRL+C组合键的功能是:复制CTRL+V组合键的功能是:粘贴CTRL+X组合键的功能是:剪切CTRL+Z组合键的功能是: 撤销ALT+PRINTSCREEN组合键的功能是:复制当前窗口、对话框或其他对象到剪贴板中任务栏隐藏时通过什么组合键可以看到任务栏:Ctrl+Alt+Del进行窗口切换的组合键是:ALT+Tab4.“画图”应用程序默认保存文件类型是:*.png“记事本”应用程序默认保存文件类型是: *.txt.DOC是什么文件类型Word文档.EXE是什么文件类型可执行文件(程序文件)5.鼠标的基本操作方法包括:指向、单击、双击和拖动鼠标指针附近有漏沙钟表示当前的状态是: 沙漏是等待,因为程序先是从硬盘上读取,然后再到内存,芯片在其期间进行运算,再没真正的打开程序时,系统认为它没正真的启动6.资源管理器左下角窗格(即”文件夹”窗口)显示的是:系统中的所有资源以分层树型的结构显示出来7.一般情况下,对文件进行重命名时,不应该修改文件的扩展名,因为: 如果修改了后缀名则会导致文件属性更改,文件无法打开8.文件的属性主要包括哪些:“只读”、“存档”、“隐藏”9.选择多个连续的文件可以采用哪些方法:使用鼠标先选定第一个文件或文件夹,然后按住Shift键,用鼠标单击最后一个文件或文件夹,这样在第一个对象和最后一个对象之间的所有文件或文件夹将全部被选中,包括第一个和最后一个文件或文件夹。
《操作系统》存储管理实验报告
《操作系统》存储管理实验报告操作系统是计算机系统中最基础、最核心的软件之一,负责管理计算机硬件资源和提供资源的分配与调度。
而存储管理是操作系统中的重要组成部分,它负责管理计算机的内存,包括内存的分配、回收、保护等操作。
本文将针对存储管理进行实验,并撰写实验报告。
本次实验主要涉及以下内容:内存的分配与回收、内存的保护。
实验过程中,我首先根据操作系统的要求,设计了相应的算法用于内存的分配与回收。
并通过编写程序,验证了算法的正确性。
随后,我进一步研究了内存的保护机制,通过设置访问权限位和访问控制表,实现了对内存的合理保护。
在内存的分配与回收方面,我设计了一种简单的算法,首次适应算法。
具体实现如下:首先,将内存分为若干个块,每个块的大小为固定值。
当需要分配内存时,首先遍历内存块列表,找到第一个大小合适的块,将其分配给进程。
当进程终止时,将其占用的内存块回收,以便后续进程使用。
通过编写程序进行测试,结果表明该算法能够正确地进行内存的分配与回收。
在内存的保护方面,我采用了访问权限位和访问控制表的方式进行。
具体实现如下:首先,为每个进程分配一组访问权限位,记录了该进程能够访问的内存区域。
同时,设置一个访问控制表,记录了每个内存块的权限。
当进程访问一些内存块时,首先检查该进程的访问权限位,再与访问控制表中的权限进行比较,以确定该进程是否有权限访问该内存块。
通过编写程序进行测试,证明了该机制能够有效地保护内存。
总结来说,本次实验主要涉及了操作系统中的存储管理部分,包括内存的分配与回收、内存的保护。
通过设计算法和编写程序,我成功地实现了这些功能,并验证了其正确性。
通过本次实验,我进一步加深了对操作系统存储管理的理解,提高了编程和设计的能力。
操作系统课程设计试验报告2
四川大学操作系统课程设计报告学院:软件学院专业:软件工程年级:2014级组编号:组成员:张弛提交时间:2016年3月15日指导教师评阅意见:.. . . .指导教师评阅成绩:XXX1:XXX1:XXX1:XXX1:XXX1:实验项目一项目名称:Week02实验目的:熟悉Linux的使用实验时间:2016.3.15人员分工:实验环境:Ubuntu 15.10实验内容:∙Lab1---设置网络地址按以下步骤设置网络地址,并截图说明:○打开终端○输入ifconfig命令查看当前网络设置(截图表示)○使用ping命令确定要设置的IP地址未被占用○用ifconfig命令来设置虚拟机的IP地址命令格式:ifconfig eth0 IP○用ifconfig命令来查看网络状态,确认设置是否成功(截图表示)∙Lab2 --- 修改配置文件按以下步骤,通过修改网络配置文件来配置网络1.打开终端2.输入ifconfig命令查看当前网络状态(截图表示)3.使用ping命令确定要设置的IP地址未被占用4.在图形界面下进入目录/etc/sysconfig/network-scripts5.打开文件ifcfg-eth0,保留以下已有的选项,添加没有的选项,删除或注释文件中多余的选项:(截图表示)DEVICE=eth0IPADDR=192.168.0.110(该为新的IP地址)NETMASK=255.255.255.0GATEWAY=10.255.255.254(可选,该为本网络的网关地址)ONBOOT=yes1.保存配置文件并在终端输入命令 service network restart2.在终端输入命令ifconfig eth0来查看是否操作成功(截图表示)∙Lab3 --- SSH安装和使用按以下步骤来实现SSH在Windows系统上的安装和使用,并截图1.安装SSH2.从桌面启动SSH Secure File Transfer Client3.点击Quick Connect按钮4.在弹出的窗口中,在Hostname中输入虚拟机的IP地址,UserName中输入用户名(一般为root),其他的保持默认,然后点击Connect按钮5.在弹出的窗口中输入虚拟机密码(截图表示)6.连接成功后将主机上的以自己学号命名的word文件拷贝到虚拟机上的/usr/local/目录下(截图表示)7.从桌面启动SSH Secure Shell Client并连接8.连接成功后用cd命令进入目录/usr/local9.输入ls命令查看我们传输的文件是否存在(截图表示)∙Lab4 --- VMwareTools安装和使用按以下方式使用VmwareTools来Windows和虚拟机下的Linux之间的文件传输,并截图1.在虚拟机上点击菜单VM并选择Install Vmware Tools2.用cd命令进入目录/mnt/cdrom3.用ls查看是否有VMwareTools-XXX.tar.gz文件(截图表示)4.拷贝此文件:cp VMareTools-XXX.tar.gz /usr/local5.用cd命令进入目录/usr/local并用ls命令确认VMareTools-XXX.tar.gz已存在(截图表示)6.解压此文件 tar -zxvf VMareTools-XXX.tar.gz7.进入目录cd vmware-tools-distrib8.执行安装 ./vmware-install.pl安装过程中要求做一些配置,只需要敲回车即可,一直到安装完成。
操作系统课内实验报告
西安交通大学实验报告操作系统实验报告刘烜乐享科技计算机36班操作系统实验实验一:用户接口实验实验目的1)理解面向操作命令的接口Shell。
2)学会简单的shell编码。
3)理解操作系统调用的运行机制。
4)掌握创建系统调用的方法。
操作系统给用户提供了命令接口和程序接口(系统调用)两种操作方式。
用户接口实验也因此而分为两大部分。
首先要熟悉Linux的基本操作命令,并在此基础上学会简单的shell 编程方法。
然后通过想Linux内核添加一个自己设计的系统调用,来理解系统调用的实现方法和运行机制。
在本次实验中,最具有吸引力的地方是:通过内核编译,将一组源代码变成操作系统的内核,并由此重新引导系统,这对我们初步了解操作系统的生成过程极为有利。
实验内容1)控制台命令接口实验该实验是通过“几种操作系统的控制台命令”、“终端处理程序”、“命令解释程序”和“Linux操作系统的bash”来让实验者理解面向操作命令的接口shell和进行简单的shell 编程。
查看bash版本。
在 shell 提示符下输入:$echo $BASH_VERSION我们的版本是(2)建立 bash 脚本,输出 Hello word在编辑器中输入以下内容#!/bin/bashecho Hello World!执行脚本使用指令:$./script编写bash脚本,统计/my目录下c语言文件的个数通过 bash 脚本,可以有多种方式实现这个功能,而使用函数是其中个一个选择。
在使用函数之前,必须先定义函数。
进入自己的工作目录,编写名为 count 的文件脚本程序:#! /bin/bashfunction count{echo –n " Number of matches for $1: " #接收程序的第一个参数ls $1|wc –l #对子程序的第一个参数所在的目录进行操作}将 count 文件复制到当前目录下,然后在当前目录下建立文件夹,在 my 目录下建立几个 c 文件,以便用来进行测试2)系统调用实验该实验是通过实验者对“Linux操作系统的系统调用机制”的进一步了解来理解操作系统调用的运行机制;同时通过“自己创建一个系统调用mycall()”和“编程调用自己创建的系统调用”进一步掌握创建和调用系统调用的方法。
操作系统实验报告1
《操作系统》实验报告实验序号:01 实验项目名称:操作系统环境学号1107xxx 姓名xxx 专业、班级软件工程1103 实验地点计—502 指导教师徐冬时间2013.9.23 实验目的1) 了解和学习Windows系统管理工具及其使用;2) 熟悉Windows系统工具的内容和应用;由此,进一步熟悉Windows操作系统的应用环境。
工具/准备工作在开始本实验之前,请回顾教科书的相关内容。
需要准备一台运行Windows 操作系统的计算机。
实验内容与步骤1. 计算机管理2. 事件查看器3. 性能监视4. 服务5. 数据库 (ODBC)为了帮助用户管理和监视系统,Windows提供了多种系统管理工具,其中最主要的有计算机管理、事件查看器和性能监视等。
如图2所示。
图2 基于虚拟机的操作系统计算环境管理步骤1:登录进入Windows。
步骤2:在“开始”菜单中单击“设置”-“控制面板”命令,双击“管理工具”图标。
在本地计算机“管理工具”组中,有哪些系统管理工具,基本功能是什么:1) Internet 信息服务;管理IIS,Internet 和Intranet站点的WEB服务器。
2) Server Extensions 管理器;Server Extensions管理器。
3)计算机管理;管理磁盘以及使用其他系统工具来管理本地或远程的计算机。
4)性能;显示系统性能图表以及配置数据日志和警报。
5)本地安全策略;查看和修改本地安全策略,如用户权限和审核策略。
6)事件查看器;显示来自于Windows和其他程序的监视与排错消息。
7)组件服务;配置和管理COM+应用程序。
1. 计算机管理使用“计算机管理”可通过一个合并的桌面工具来管理本地或远程计算机,它将几个Windows管理实用程序合并到一个控制台目录树中,使管理员可以轻松地访问特定计算机的管理属性和工具。
步骤3:在“管理工具”窗口中,双击“计算机管理”图标。
“计算机管理”使用的窗口与“Windows资源管理器”相似。
《操作系统》课程实验报告
《操作系统》课程实验报告一、实验目的本次《操作系统》课程实验的主要目的是通过实际操作和观察,深入理解操作系统的工作原理、进程管理、内存管理、文件系统等核心概念,并掌握相关的操作技能和分析方法。
二、实验环境1、操作系统:Windows 10 专业版2、开发工具:Visual Studio Code3、编程语言:C/C++三、实验内容(一)进程管理实验1、进程创建与终止通过编程实现创建新进程,并观察进程的创建过程和资源分配情况。
同时,实现进程的正常终止和异常终止,并分析其对系统的影响。
2、进程同步与互斥使用信号量、互斥锁等机制实现进程之间的同步与互斥。
通过模拟多个进程对共享资源的访问,观察并解决可能出现的竞争条件和死锁问题。
(二)内存管理实验1、内存分配与回收实现不同的内存分配算法,如首次适应算法、最佳适应算法和最坏适应算法。
观察在不同的内存请求序列下,内存的分配和回收情况,并分析算法的性能和优缺点。
2、虚拟内存管理研究虚拟内存的工作原理,通过设置页面大小、页表结构等参数,观察页面的换入换出过程,以及对系统性能的影响。
(三)文件系统实验1、文件操作实现文件的创建、打开、读取、写入、关闭等基本操作。
观察文件在磁盘上的存储方式和文件系统的目录结构。
2、文件系统性能优化研究文件系统的缓存机制、磁盘调度算法等,通过对大量文件的读写操作,评估不同优化策略对文件系统性能的提升效果。
四、实验步骤(一)进程管理实验步骤1、进程创建与终止(1)使用 C/C++语言编写程序,调用系统函数创建新进程。
(2)在子进程中执行特定的任务,父进程等待子进程结束,并获取子进程的返回值。
(3)通过设置异常情况,模拟子进程的异常终止,观察父进程的处理方式。
2、进程同步与互斥(1)定义共享资源和相关的信号量或互斥锁。
(2)创建多个进程,模拟对共享资源的并发访问。
(3)在访问共享资源的关键代码段使用同步机制,确保进程之间的正确协作。
(4)观察并分析在不同的并发情况下,系统的运行结果和资源竞争情况。
操作系统实验报告
实 验 报 告
成绩
教 师:方敏
2016 年 12月 17日
班 级:
学 号:140607815
姓 名:黄杨
实验地点:E-Ⅲ区208
实验时间:2016.10.13—2016.12.17
实验一创建进程
【实验软硬件环境】
VC
【实验内容】
实验内容:父进程创建一个有名事件,由子进程发送事件信号,父进程获取事件信号后进行相应的处理
实验三信号通信
【实验软硬件环境】
VC++
【实验内容】
父进程创建一个有名事件,由子进程发送事件信号,父进程获取事件信号后进行相应的处理。
【实验程序及分析】
父进程程序:
// Processs.cpp : Defines the entry point for the console application.
return 0;
}
else{
fprintf(fp,"XiDian University");
fclose(fp);
printf("数据已经写入成功\n");
}
FILE *qp;
if((qp = fopen("D:\\Test1\\abc.txt","r"))== NULL){
printf("读文件打开失败!\n");
【实验原理】
父进程创建子进程,实现多个进程并发执行,提高计算机的运行效率。
【实验程序及分析】
试验程序源代码如下:
父进程部分代码:
// test1.cpp : Defines the entry point for the console application.
操作系统实验报告(DOC)
实验六设备管理实验目的1、理解设备管理的概念和任务。
2、掌握独占设备的分配、回收等主要算法的原理并编程实现。
实验内容与基本要求1、在Windows系统中,编写程序实现对独占设备的分配和回收的模拟,该程序中包括:建立设备类表和设备表、分配设备和回收设备的函数。
实验报告内容1、独占设备的分配、回收等主要算法的原理。
为了提高操作系统的可适应性和可扩展性,现代操作系统中都毫无例外地实现了设备独立性,又叫做设备无关性。
设备独立性的含义是,应用程序独立于具体使用的物理设备。
为了实现独占设备的分配,系统设置数据表格的方式也不相同,在实验中只要设计合理即可。
这里仅仅是一种方案,采用设备类表和设备表。
(1)数据结构操作系统设置“设备分配表”,用来记录计算机系统所配置的独占类型、台数以及分配情况。
设备分配表可由“设备类表”和“设备表”两部分组成,如下图(2)设备分配当进程申请某类设备时,系统先查“设备类表”如果该类设备的现存台数可以满足申请要求 则从该类设备的“设备表”始址开始依次查该类设备在设备表中的登记项,找出“未分配”的设备分配给进程。
分配后要修改设备类表中的现存台数,把分配给进程的设备标志改为“已分配”且填上占用设备的进程名。
然后把设备的绝对号与相对号的对应关系通知用户,以便用户在分配到的设备上装上存储介质。
(3)设备回收当进程执行结束撤离时应归还所占设备,系统根据进程名查设备表,找出进程占用设备的登记栏,把标志修改为“未分配”清除进程名。
同时把回收的设备台数加到设备类表中的现存台数中。
2、程序流程图。
主体流程设备分配设备回收3、程序及注释。
#include<stdio.h>#include<string.h>#include<stdlib.h>#define false 0#define true 1#define n 4 /*宏定义 用于修改设备类型数目*/#define m 10 /*宏定义 用于修改设备数目*/struct /*该结构体用于定义设备类表各信息*/{ char type[10]; /*设备类型名*/int count; /*拥有的设备总台数*/int remain; /*现存的可用设备台数*/ int address; /*该类设备设备表中的起始地址*/ }equiptype[n]; /*系统设备类型为n*/struct /*该结构体用于定义设备表各信息*/{int number; /*设备绝对编号*/int lnumber; /*设备相对编号*/int status; /*设备好坏状态*/int remain; /*设备是否已被分配*/ char jobname[4]; /*占有设备的作业名*/ } equipment[m]; /*系统设备数为m*/ /******子函数作业设备分配*******/allocate(char *J,char *type,int cc){int i,t,j;i=0;while(i<n&&strcmp(equiptype[i].type,type)!=0) /*查找欲申请分配的设备类型 strcmp函数用于比较equiptype[i].type与type的大小若相等则返回0*/i++;if(i>=n) /*若没有找到欲申请设备*/ {printf("没有找到欲分配的设备,分配失败!");return(false);}if(equiptype[i].remain<1) /*欲申请设备现存可用台数不足*/ {printf("该类设备数量不足 分配失败!");return(false);}t=equiptype[i].address; /* 取出该类设备在设备表中的起地址赋给t*/while(!(equipment[t].status==1 && equipment[t].remain==0))t++; /*该设备类型起始地址加一*/ equiptype[i].remain--; /*剩余设备数减一*/equipment[t].remain=1; /*状态改为已分配*/strcpy(equipment[t].jobname,J); /*strcpy为字符串拷贝函数把J中的字符串拷贝到equipment[t].jobname中*/equipment[t].lnumber=cc; /*设备相对号写入cc*/}/**********************子函数 作业设备回收*****************************/reclaim(char *J,char *type){int i,t,j,k,nn;i=0;while(i<n&&strcmp(equiptype[i].type,type)!=0) /*查找欲申请归还的设备类型 strcmp函数用于比较equiptype[i].type与type的大小若相等则返回0*/i++;if(i>=n)/*若没有找到该类设备*/{printf("无该类设备,设备回收失败!");return(false);} t=equiptype[i].address; /*取出该类设备在设备表中的起始地址赋给t*/j=equiptype[i].count; /*取出该类设备的数量赋给j*/k=0;nn=t+j;for(;t<nn;t++)if(strcmp(equipment[t].jobname,J)==0&&equipment[t].remain==1) /*若占用某个设备的作业与欲回收的作业相同且状态为已分配*/{equipment[t].remain=0; /*则将其状态改为未分配*/k++; /*回收设备计数*/}equiptype[i].remain= equiptype[i].remain+k; /*该类设备剩余设备数加k*/if(k==0) /*若回收设备计数值k为0,*/printf("本作业没有占用这类资源!/n");}/**********************主函数*****************************/ void main( ){char J[4];int i,mm,a;char type[10];printf(" *******************\n\ *******************\n\);printf("设备类初始化\n ");for(i=0;i<4;i++) /*输入设备类表初始信息*/{printf("请输入相应设备名称 ");scanf("%s",&equiptype[i].type);printf("请输入相应设备的数量 ");scanf("%d",&equiptype[i].count);printf("请输入当前空闲设备数量 ");scanf("%d",&equiptype[i].remain);printf("请输入设备表起始地址 ");scanf("%d",&equiptype[i].address);}for(i=0;i<10;i++) /*初始化设备表*/{equipment[i].number=i;equipment[i].status=1;equipment[i].remain=0;}while(1){ printf("\n0-退出,1-分配,2-回收,3-显示"); /*功能选择界面*/printf("\n请选择功能(0-3):");scanf("%d",&a);switch(a){case 0 : /*a=0程序结束*/exit(0);case 1 : /*a=1分配设备*/ printf("请输入作业名、作业所需设备类型和设备相对号\n");scanf("%s%s%d",J,type,&mm);allocate(J,type,mm); /*分配设备*/break;case 2: /*a=2回收设备*/printf("请输入作业名和作业归还的设备类\n");scanf("%s%s",J,type); /*输入要回收的作业名及对应的设备类*/reclaim(J,type); /*回收设备*/break;case 3: /*a=3 输出设备类表和设备表的内容*/printf("输出设备类表!\n"); /*输出设备类表内容*/printf(" 设备类型设备总量空闲好设备起始地址\n");for(i=0;i<n;i++)printf("%9s%16d%22d%14d\n",equiptype[i].type,equiptype[i].count,equiptype[i].remain,equiptype[i].address);printf("输出设备表:\n"); /*输出设备表内容*/printf("绝对号好/坏已/未分配占用作业名相对号\n");for(i=0;i<m;i++)printf("%3d%11d%15d%15s%9d\n",equipment[i].number,equipment[i].status,equipment[i].remain,equipment[i].jobname,equipment[i].lnumber);}}}4、运行结果以及结论。
操纵系统实验报告
一、实验目的1. 了解操作系统的基本概念、功能及分类。
2. 掌握操作系统的主要组成部分及其作用。
3. 熟悉操作系统的基本操作,如进程管理、内存管理、文件系统等。
4. 深入理解操作系统的调度策略、同步机制及死锁问题。
二、实验环境1. 操作系统:Windows 102. 编程语言:C/C++3. 开发工具:Visual Studio三、实验内容及步骤1. 进程管理实验(1)实验目的:了解进程的基本概念、进程状态及进程调度。
(2)实验步骤:① 编写一个C/C++程序,创建多个进程,观察进程状态变化。
② 实现进程的创建、回收、切换等功能。
③ 分析进程调度算法(如先来先服务、短作业优先、时间片轮转等)对系统性能的影响。
2. 内存管理实验(1)实验目的:了解内存管理的基本概念、分配策略及碎片问题。
(2)实验步骤:① 编写一个C/C++程序,模拟内存分配过程,观察内存碎片现象。
② 实现内存的分配、回收、扩展等功能。
③ 分析内存分配策略(如固定分区、可变分区、分页、分段等)对系统性能的影响。
3. 文件系统实验(1)实验目的:了解文件系统的基本概念、目录结构及文件操作。
(2)实验步骤:① 编写一个C/C++程序,实现文件系统的创建、删除、读写等操作。
② 实现目录结构的创建、修改、删除等功能。
③ 分析文件系统性能(如访问速度、存储空间利用率等)的影响因素。
4. 调度策略实验(1)实验目的:了解操作系统的调度策略,分析不同调度算法对系统性能的影响。
(2)实验步骤:① 编写一个C/C++程序,模拟进程调度过程,观察不同调度算法的效果。
② 实现先来先服务、短作业优先、时间片轮转等调度算法。
③ 分析不同调度算法的优缺点及适用场景。
5. 同步机制实验(1)实验目的:了解操作系统的同步机制,解决进程竞争资源问题。
(2)实验步骤:① 编写一个C/C++程序,模拟进程竞争资源场景,观察进程同步问题。
② 实现互斥锁、信号量等同步机制。
《操作系统》实验报告(2)
c.将subdir目录的读权限去掉,看看是否能用ls命令看到其中内容?
权限不够
(三)Shell程序设计
1.上机编辑、执行实验内容中的例1~例6过程,写出每个脚本(例1~例5)的功能和执行结果;
然后把t01.txt复制一个新文件t03.txt,catt01.txt>t02.txt;
用cat命令将f01.txt的内容追加到t01.txt的末尾,catf01.txt>> t01.txt;
再用diff命令比较t01.txt,t02.txt和t03.txt,比较t01.txt,t02.txt:diff t01.txt t02.txt,结果是否相同:__相同___;比较t01.txt,t03.txt:diff t01.txt t03.txt,结果是否相同:不相同;比较t02.txt,t03.txt:diff t02.txt t03.txt,结果是否相同:不相同。出现上述结果的原因是:______________________________________________________________________________。
2.修改例5,使脚本中不出现break循环控制语句;
3.编写一个Shell过程完成如下功能:
a.合并两个$1、$2文件为$3,并显示内容。
b.如果缺少$3,那么先报告缺少$3,将合并后的内容输出到totaltext.txt,并显示内容。
c.如果缺少$2、$3那么先报告缺少$2、$3,只显示$1的内容。
b.用ln命令给t03.txt建立一个符号链接t04.txt,ln–st03.txt t04.txt;用cat命令看看t04.txt,___cat t04.txt_____;然后删去t03.txt,___rm t03.txt____;再用cat命令看看t04.txt,___cat t04.txt___;结果是:___t04.txt为空____
西安交通大学数字逻辑电路试验报告
电子技术实验报告交通控制器的分析与设计班级:姓名:学号:日期:2016年6月联系电话:一、实验目的 (3)二、项目设计概要 (3)三、系统设计方案 (4)四、测试结果及分析 (9)五、项目总结 (10)六、结束语 (10)七、参考书 (10).实验目的数字逻辑电路专题实验是紧紧围绕数字逻辑这门课程进行的一个有实践性特质的课程,主要考察的是对于数字逻辑这门课程中比较重要的知识点的掌握程度和灵活运用程度,也考察了实际操作能力和对于特殊情况和意外情况的处理能力。
通过对于译码器编码器等器件的实际操作和对相应变成软件的实际应用,达到对于这门课程更为深入理解这一目的。
同时,为解决实际生活中的问题有一定的指导意义,也能更好地对实际生活中的一些组合部件有更好地认识。
项目设计概要1.设计实现的目标设计一个由一条主干道和一条支干道的汇合点形成的十字交叉路口的交通灯控制器,具体要求如下:(1)主、支干道各设有一个绿、黄、红指示灯,两个显示数码管。
(2)主干道处于常允许通行状态,而支干道有车来才允许通行。
(3)当主、支道均有车时,两者交替允许通行,主干道每次放行45 s,支干道每次放行25 s,在每次由亮绿灯变成亮红灯的转换过程中,要亮5 s的黄灯作为过渡,并进行减计时显示。
2.整体设计概述交通控制器拟由单片的CPLD/FPGA来实现,经分析设计要求,拟定整个系统由9个单元电路组成,如图所示。
JT(WE3.项目设计特点我们在项目设计过程中采用模块化设计思想,同时用变量的方式来完成计数的设计,用计数器来实现显示这一特点,使得设计变得简单。
三.系统设计方案1.系统功能模块设计示意图:2.电路模块设计输入:实验板时钟输出:七段数码管电路模块的设计:(1)交通灯控制器:将题设的要求把电路分为ABCD四个状态,A为主干道为绿灯,B为主干道为黄灯,C 为主干道为红灯,D为主干道为红灯,旁道为黄灯。
用特设的一个变量S,完成电路的即使功能,使得电路可以区分45s, 25s等时间点,并且通过if语句完成状态之间的改变。
操作系统实验报告
操作系统实验报告操作系统是计算机科学中十分重要的一门课程,本次实验是关于操作系统的,通过实验,我们可以更深入地了解操作系统的相关知识和操作。
本篇文章将着重介绍本次操作系统实验的内容和实验过程中的收获。
一、实验内容本次实验内容主要涉及操作系统的进程、线程和进程同步三部分。
具体内容包括:1. 进程的创建和管理2. 线程的创建和管理3. 进程同步的实现在实验过程中,我们将分别使用C语言和Linux操作系统实现上述功能。
二、实验过程1. 进程的创建和管理在这一部分实验中,我们要创建多个进程,实现进程的调度和管理功能。
我们采用了Linux系统下的fork()函数,用于创建子进程。
在程序运行时,首先创建一个父进程,然后使用fork()函数创建四个子进程,每个子进程都有自己的进程号(pid),并在屏幕上输出该进程号以示区分。
为了实现进程的调度功能,我们在代码中加入了sleep()函数,用于将进程挂起一段时间,然后再轮流执行其他进程。
2. 线程的创建和管理在这一部分实验中,我们使用了C语言的POSIX线程库pthread.h,实现多线程的功能。
同样地,我们采用了Linux系统下的fork()函数来创建线程。
在代码运行时,我们创建了两个线程,并在屏幕上输出线程号(tid)以示区分。
为了实现线程的调度和管理功能,我们在代码中加入了pthread_join()函数,用于等待线程的执行完成。
3. 进程同步的实现在这一部分实验中,我们使用了Linux系统下的进程同步工具——信号量(semaphore)。
在代码中,我们使用sem_init()函数创建信号量,使用sem_wait()函数阻塞进程或线程,使用sem_post()函数释放进程或线程。
为了更好地理解信号量的工作原理,我们将代码分为生产者和消费者两部分,其中生产者用于向缓冲区添加数据,消费者则用于删除数据。
在这个过程中,我们需要使用信号量控制生产者和消费者的数量,避免出现生产过多或消费过多的情况。
《操作系统》课程综合性的实验报告
《操作系统》课程综合性的实验报告一、实验目的本次《操作系统》课程的综合性实验旨在通过实际操作和实践,深入理解操作系统的基本原理、功能和运行机制。
具体目标包括熟悉操作系统的进程管理、内存管理、文件系统管理以及设备管理等核心模块,提高对操作系统的整体认知和应用能力。
二、实验环境本次实验在以下环境中进行:操作系统:Windows 10 专业版开发工具:Visual Studio 2019编程语言:C++三、实验内容及步骤(一)进程管理实验1、创建多个进程使用 C++中的多线程库,创建多个进程,并观察它们的并发执行情况。
通过设置不同的优先级和资源需求,研究进程调度算法对系统性能的影响。
2、进程同步与互斥实现生产者消费者问题,使用信号量、互斥锁等机制来保证进程之间的同步和互斥。
观察在不同并发情况下,数据的正确性和系统的稳定性。
(二)内存管理实验1、内存分配与回收模拟内存分配算法,如首次适应算法、最佳适应算法和最坏适应算法。
通过随机生成内存请求,观察不同算法下内存的利用率和碎片情况。
2、虚拟内存管理研究虚拟内存的工作原理,通过设置页面大小和页表结构,观察页面置换算法(如 FIFO、LRU 等)对内存访问性能的影响。
(三)文件系统管理实验1、文件操作创建、读取、写入和删除文件,了解文件系统的基本操作和数据结构。
2、文件目录管理实现文件目录的创建、遍历和搜索功能,研究目录结构对文件访问效率的影响。
(四)设备管理实验1、设备驱动程序模拟编写简单的设备驱动程序,模拟设备的输入输出操作,如键盘输入和屏幕输出。
2、设备分配与调度研究设备分配算法,如先来先服务和优先级算法,观察设备的使用情况和系统的响应时间。
四、实验结果与分析(一)进程管理实验结果分析1、在创建多个进程的实验中,发现高优先级进程能够更快地获得CPU 资源,系统响应时间更短。
但过度提高某些进程的优先级可能导致其他进程饥饿。
2、对于进程同步与互斥问题,正确使用信号量和互斥锁能够有效地保证数据的一致性和系统的稳定性。
西安交通大学操作系统课内实验报告全解
西安交通大学实验报告——操作系统原理课内实验姓名:班级:学号:实验一用户接口实验一、实验目的1、理解并掌握面向操作命令的接口 Shell,学会简单的shell编码。
2、理解操作系统调用的运转体制,掌握创立系统调用的方法。
二、实验内容1、控制台命令接口实验理解面向操作命令的接口shell和进行简单的shell编程。
该实验是经过“几种操作系统的控制台命令”、“终端办理程序”、“命令解说程序”和“Linux操作系统的bash”来让实验者理解面向操作命令的接口shell和进行简单的shell 编程。
查察bash版本。
编写bash脚本,统计/my目录下c语言文件的个数2)系统调用实验。
2、系统调用实验理解操作系统调用的运转体制。
该实验是经过实验者对“Linux操作系统的系统调用体制”的进一步认识来理解操作调用的运转体制;同时经过“自己创立一个系统调用mycall()”和“编程调用自己的系统调用”进一步掌握创立和调用系统调用的方法。
编程调用一个系统调用fork(),察看结果。
编程调用创立的系统调用foo(),察看结果。
自己创立一个系统调用mycall(),实现功能:显示字符串到屏幕上。
编程调用自己创立的系统调用。
系统创立三、实验准备为了使用户经过操作系统达成各项管理任务,操作系统一定为用户供应各样接口来实现人机交互。
经典的操作系统理论将操作系统的接口分为控制台命令和系统调用两种。
前者主要供应给计算机的操作人员对计算机进行各样控制;尔后者则供应个程序员,使他们能够方便地使用计算机的各样资源。
四、实验步骤及结果1、控制台命令接口实验1)查察bash版本操作:在shell提示符下输入:$echo$BASH_VERSION结果:版本是(1)-release2)成立bash脚本,输出Helloword操作:在编写器中输入以下内容#!/bin/bashechoHelloWorld!结果:操作:履行脚本使用指令:$./text结果:(3)编写bash脚本:统计/my目录下c语言文件的个数经过bash脚本,能够有多种方式实现这个功能,而使用函数是此中个一个选择。
西安交大操作系统实验报告
西安交通大学操作系统专题实验报告班级:学号:姓名:2022年4月25日目录1内核编译与系统调用 (1)1.1实验目的 (1)1.2实验内容 (1)1.3实验思想(或流程图) (1)1.4实验步骤 (1)1.5测试数据设计 (3)1.6程序运行初值及运行结果分析 (3)1.7实验总结 (4)1.7.1实验中的问题与解决过程 (4)1.7.2实验收获 (5)1.7.3意见与建议 (5)1.8附件 (5)1.8.1附件1 程序 (5)1.8.2附件2 MakeFile (8)1.8.3附件3 Readme (8)2 进程软中断与管道通信 (13)2.1实验目的 (13)2.2实验内容 (13)2.3实验思想(或流程图) (13)2.4结果分析 (15)2.5实验总结 (16)2.6源代码 (17)3 模块编程与字符设备驱动 (20)3.1实验目的 (20)3.2实验内容 (20)3.3实验总结 (21)3.4附件 (22)1内核编译与系统调用1.1实验目的掌握系统调用的设计过程,为以后设计更复杂系统奠定基础。
1.2实验内容安装Linux,熟悉Linux的操作,并编译内核,构建、使用自己的Linux内核设计系统调用:设计、添加自己的系统调用,并重新编译内核予以验证为Linux内核设计添加一个系统调用,将系统的相关信息(CPU型号、操作系统的版本号、系统中的进程等,类似于Windows的任务管理器)以文字形式列表显示于屏幕,并编写用户程序予以验证。
请参阅proc文件系统的相关说明,读取proc文件系统的相关信息,可参考实验指导书的proc编程实验1.3实验思想(或流程图)系统调用是应用程序和操作系统内核之间的功能接口,其主要目的使用户可以使用操作系统提供的有关设备管理、输入/ 输出系统、文件系统和进程控制、通信以及存储管理等方面的功能 ,而不必了解系统程序的内部结构和有关硬件细节,从而起到减轻用户负担和保护系统以及提高资源利用率的作用。
操作系统的安装实验报告
操作系统的安装实验报告
《操作系统的安装实验报告》
实验目的:通过实际操作,掌握操作系统的安装过程及注意事项。
实验内容:本次实验选择了Windows 10操作系统进行安装。
首先,准备好安装光盘或U盘,并将其插入计算机。
然后,重启计算机并按下相应的按键进入BIOS设置界面,将启动顺序设置为光盘或U盘优先。
接着,按照提示进入安装界面,选择安装语言、时区等相关选项。
在分区界面,选择安装位置并进行分区设置。
最后,按照提示完成安装过程,等待系统自动重启。
实验结果:经过一系列操作,成功安装了Windows 10操作系统。
在安装过程中,需要注意的是选择合适的安装位置和分区设置,以及在安装过程中不要中断电源或操作。
另外,安装完成后需要及时更新系统补丁和驱动程序,保证系统的稳定性和安全性。
实验总结:通过本次实验,我对操作系统的安装过程有了更深入的了解,并掌握了一些实用的技巧和注意事项。
在今后的工作和学习中,我将能够更加熟练地进行操作系统的安装和维护工作,为计算机的运行和使用提供更好的支持。
通过本次实验,我对操作系统的安装过程有了更深入的了解,并掌握了一些实用的技巧和注意事项。
在今后的工作和学习中,我将能够更加熟练地进行操作系统的安装和维护工作,为计算机的运行和使用提供更好的支持。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统实验报告实验一:用户接口实验一.实验目的1.理解面向操作命令的接口Shell。
2.学会简单的shell编码。
3.理解操作系统调用的运行机制。
4.掌握创建系统调用的方法。
操作系统给用户提供了命令接口和程序接口(系统调用)两种操作方式。
用户接口实验也因此而分为两大部分。
首先要熟悉Linux的基本操作命令,并在此基础上学会简单的shell编程方法。
然后通过想Linux内核添加一个自己设计的系统调用,来理解系统调用的实现方法和运行机制。
在本次实验中,最具有吸引力的地方是:通过内核编译,将一组源代码变成操作系统的内核,并由此重新引导系统,这对我们初步了解操作系统的生成过程极为有利。
二.实验内容1)控制台命令接口实验该实验是通过“几种操作系统的控制台命令”、“终端处理程序”、“命令解释程序”和“Linux操作系统的bash”来让实验者理解面向操作命令的接口shell 和进行简单的shell编程。
➢查看bash版本。
➢编写bash脚本,统计/my目录下c语言文件的个数2)系统调用实验该实验是通过实验者对“Linux操作系统的系统调用机制”的进一步了解来理解操作系统调用的运行机制;同时通过“自己创建一个系统调用mycall()”和“编程调用自己创建的系统调用”进一步掌握创建和调用系统调用的方法。
➢编程调用一个系统调用fork(),观察结果。
➢编程调用创建的系统调用foo(),观察结果。
➢自己创建一个系统调用mycall(),实现功能:显示字符串到屏幕上。
➢编程调用自己创建的系统调用。
三.实验步骤系统调用实验:1.首先将Linux-3.0.tar.bz2拷贝到/usr/src目录下——命令:cp linux-3.0.tar.bz2 /usr/src/2.打开终端,获得root权限——命令:sudo –s3.进入/usr/src目录——命令:cd /usr/src4.解压linux源码——命令:tar xvzf linux-3.0.tar.bz25.进入目录linux-3.0.5——命令:cd linux-3.06.添加系统调用——操作:gedit kernel/myservice.c 在文本编辑器中添加#include <linux/kernel.h>#include <linux/linkage.h>asmlinkage void sys_mycall(){printk(KERN_INFO "Hello, world!\n");return;}7.修改kernel/Makefile添加生成myservice.c添加到Makefile的编译规则中:obj-y += myservice.o8..修改arch/x86/include/asm/unistd_32.h,添加以下内容:#define __NR_mycall SYS_ID//SYS_ID表示新添加系统调用的调用号并修改文件中的NR_syscalls,将其值增加19.修改arxh/x86/include/asm/syscalls.h添加以下内容:asmlinkage void sys_mycall();10.修改arch/x86/kernel/syscall_table_32.S,添加以下内容:.long sys_mycall11.配置内核(仅仅修改local versions即可)——命令:make menuconfig12.编译内核——命令:make –j4 bzImage(开4个线程编译)13.编译内核模块——命令:make –j4 modules14.安装内核模块——命令:make modules_install15.安装内核——命令:make install16.重启系统,在系统选择页面选择进入自己编译的linux-3.0内核17.在桌面建立测试的C程序test.c程序内容如下:#include <stdio.h>int main(int argc, char *argv[]){syscall(SYS_ID); // SYS_ID表示新添加系统调用的调用号return 0;}18.编译程序——gcc test.c –o a.out19.运行程序——./a.out20.查看内核日志(printk的输出信息在内核日志中):dmesg四.实验结果1.成功完成内核编译的任务,结果显示图如下:2.下图为添加系统调用结果五.实验小结这次实验的内核编译需要进行一系列比较花时间的操作过程,但同时也锻炼了实际动手能力,在实践中对于操作系统这门课有了进一步的了解。
同时,在本次实验中,学习了linux系统的使用方法,掌握了很多的基本命令,也明白了添加系统调用的方法,为以后的学习提供了很大的帮助。
实验四:一个简单文件系统的实现一.实验目的1.熟悉Ext文件系统的原理2.根据Ext文件系统的数据结构和构建方法,自行实现一个简单的内存文件系统二.实验内容1.设计并实现一个一级(单用户)文件系统程序a.提供以下操作:a)文件创建/删除接口命令create/deleteb)目录创建/删除接口命令mkdir/rmdirc)显示目录内容命令lsb.创建的文件不要求格式和内容2.设计并实现一个二级文件系统程序a.提供用户登录;b.文件、目录要有权限三.实验原理1.Ext文件系统结构:2.3.引导块BootBlock每个硬盘分区的开头1024字节,即0 byte至1023 byte是分区的启动扇区。
存放由ROM BIOS自动读入的引导程序和数据,但这只对引导设备有效,而对于非引导设备,该引导块不含代码。
这个块与ext2没有任何关系。
4.超级块SuperBlock每个分区均有一个super block块,定义了文件系统的全局信息,包括块的大小,总块数,空闲块,索引结点数,各种位图和i节点表的地址和大小等信息。
5.数据块位图这是ext2管理存储空间的方法。
即位图法。
每个位对应一个数据块,位值为0表示空闲,1表示已经分配。
数据块位图定义为一个块大小。
于是,一个组中的数据块个数就决定了。
假设块大小为b 字节。
可以区别的块数为b*8个6.数据块DataBlocks每个组的数据最大个数是在块大小定义后就确定了的。
所以组容量也就确定了。
假设块大小为b 字节。
那么组容量就确定为(b*8)*b字节若1块=4K,则组块大小=4K*8*4K=128M7.inode位图与数据块位图相似,用来表示索引结点是否已经被使用。
假设块大小为b 字节,每个索引结点数据结构大小为128字节。
最多可以有b*8个索引结点,索引结点表需要占用的存储空间大小为(b*8)*128字节。
即(b*8)*128/b=8*128个块8.inode表索引结点表由若干个索引结点数据结构组成,需要占用若干个块。
Ext2中的每个索引结点数据结构大小为128字节。
每个索引结点即对应一个文件或是目录。
是对其除文件名(目录名)以外的所有属性的描述。
例如:文件类型,文件创建时间,访问时间,修改时间,文件所占数据块的个数,指向数据块的指针。
其中,数据块指针是由15个元组的数据组成四.实验步骤运行结果1.根据要求编写源程序,实验源代码见附录1。
2. 运行程序,运行结果如图:1.根据提示输入help,结果如图:2.输入ls 列出根目录下的项目,然后创建文件目录c 再输入ls观察是否创建成功:5.进入文件目录c并在c中创建文件a6.打开a,并读取a7. 关闭a 9.删除a9. 删除文件目录c五.实验小结本次实验要求建立一个文件系统,由于在专业课上的基本知识学习比较薄弱,所以参考了网上的一些代码,进行了一些修改后最后获得结果。
最后,也算完成了一个简单的文件系统,具备了题目中的要求。
但在以后的学习中,还要对这一方面的知识进行一些补充。
附录1:实验源码:#include <stdio.h>#include <time.h>#include <string.h>#include <signal.h>#define DATA_BLOCK 263680 //数据块起始地址#define BLOCK_SIZE 512 //块大小#define DISK_START 0 //磁盘开始地址#define BLOCK_BITMAP 512 //块位图起始地址#define INODE_BITMAP 1024//inode 位图起始地址#define INODE_TABLE 1536//索引节点表起始地址#define INODE_SIZE 64 //struct inode的大小struct group_desc{char bg_volume_name[16]; //卷名unsigned short bg_block_bitmap; //保存块位图的块号unsigned short bg_inode_bitmap; //保存索引结点位图的块号unsigned short bg_inode_table; //索引结点表的起始块号unsigned short bg_free_blocks_count; //本组空闲块的个数unsigned short bg_free_inodes_count; //本组空闲索引结点的个数unsigned short bg_used_dirs_count; //本组目录的个数char bg_pad[4]; //填充(0xff)};struct inode{unsigned short i_mode; //文件类型及访问权限unsigned short i_blocks; //文件的数据块个数unsigned long i_size; //大小( 字节)unsigned long i_atime; //访问时间unsigned long i_ctime; //创建时间unsigned long i_mtime; //修改时间unsigned long i_dtime; //删除时间unsigned short i_block[8]; //指向数据块的指针char i_pad[24]; //填充(0xff)};struct dir_entry{ //目录项结构unsigned short inode; //索引节点号unsigned short rec_len; //目录项长度unsigned short name_len; //文件名长度char file_type; //文件类型(1: 普通文件,2: 目录.. )char name[9]; //文件名};char Buffer[512]; //针对数据块的缓冲区char tempbuf[4097]; //unsigned char bitbuf[512]; //位图缓冲区unsigned short index_buf[256];short fopen_table[16]; // 文件打开表unsigned short last_alloc_inode; // 最近分配的节点号unsigned short last_alloc_block; // 最近分配的数据块号unsigned short current_dir; // 当前目录的节点号struct group_desc super_block[1]; // 组描述符缓冲区struct inode inode_area[1]; // 节点缓冲区struct dir_entry dir[32]; // 目录项缓冲区char current_path[256]; // 当前路径名unsigned short current_dirlen;FILE *fp;void update_group_desc(){fseek(fp,DISK_START,SEEK_SET);fwrite(super_block,BLOCK_SIZE,1,fp);}void reload_group_desc()//载入组描述符{fseek(fp,DISK_START,SEEK_SET);fread(super_block,BLOCK_SIZE,1,fp);}void update_inode_bitmap()//更新inode位图{fseek(fp,INODE_BITMAP,SEEK_SET);fwrite(bitbuf,BLOCK_SIZE,1,fp);}void reload_inode_bitmap()//载入inode位图{fseek(fp,INODE_BITMAP,SEEK_SET);fread(bitbuf,BLOCK_SIZE,1,fp);}void update_block_bitmap()//更新block位图{fseek(fp,BLOCK_BITMAP,SEEK_SET);fwrite(bitbuf,BLOCK_SIZE,1,fp);}void reload_block_bitmap()//载入block位图{fseek(fp,BLOCK_BITMAP,SEEK_SET);fread(bitbuf,BLOCK_SIZE,1,fp);}void update_inode_entry(unsigned short i)//更新第i个inode入口{fseek(fp,INODE_TABLE+(i-1)*INODE_SIZE,SEEK_SET);fwrite(inode_area,INODE_SIZE,1,fp);}void reload_inode_entry(unsigned short i)//载入第i个inode入口{fseek(fp,INODE_TABLE+(i-1)*INODE_SIZE,SEEK_SET);fread(inode_area,INODE_SIZE,1,fp);}void reload_dir(unsigned short i)//更新第i个目录{fseek(fp,DATA_BLOCK+i*BLOCK_SIZE,SEEK_SET);fread(dir,BLOCK_SIZE,1,fp);}void update_dir(unsigned short i)//载入第i个目录{fseek(fp,DATA_BLOCK+i*BLOCK_SIZE,SEEK_SET);fwrite(dir,BLOCK_SIZE,1,fp);}void reload_block(unsigned short i)//载入第i个数据块{fseek(fp,DATA_BLOCK+i*BLOCK_SIZE,SEEK_SET);fread(Buffer,BLOCK_SIZE,1,fp);}void update_block(unsigned short i)//更新第i个数据块{fseek(fp,DATA_BLOCK+i*BLOCK_SIZE,SEEK_SET);fwrite(Buffer,BLOCK_SIZE,1,fp);}int alloc_block()//分配一个数据块,返回数据块号;{unsigned short cur=last_alloc_block;unsigned char con=128;int flag=0;if(super_block[0].bg_free_blocks_count==0){printf("There is no block to be alloced!\n");return(0);}reload_block_bitmap();cur=cur/8;while(bitbuf[cur]==255){if(cur==511)cur=0;else cur++;}while(bitbuf[cur]&con){con=con/2;flag++;}bitbuf[cur]=bitbuf[cur]+con;last_alloc_block=cur*8+flag;update_block_bitmap();super_block[0].bg_free_blocks_count--;update_group_desc();return last_alloc_block;}void remove_block(unsigned short del_num)//删除一个block {unsigned short tmp;tmp=del_num/8;reload_block_bitmap();switch(del_num%8)//更改block位图{case 0:bitbuf[tmp]=bitbuf[tmp]&127;break;case 1:bitbuf[tmp]=bitbuf[tmp]&191;break;case 2:bitbuf[tmp]=bitbuf[tmp]&223;break;case 3:bitbuf[tmp]=bitbuf[tmp]&239;break;case 4:bitbuf[tmp]=bitbuf[tmp]&247;break;case 5:bitbuf[tmp]=bitbuf[tmp]&251;break;case 6:bitbuf[tmp]=bitbuf[tmp]&253;break;case 7:bitbuf[tmp]=bitbuf[tmp]&254;break;}update_block_bitmap();super_block[0].bg_free_blocks_count++;update_group_desc();}//int get_inode()//分配一个inode,返回序号{unsigned short cur=last_alloc_inode;unsigned char con=128;int flag=0;if(super_block[0].bg_free_inodes_count==0){printf("There is no Inode to be alloced!\n");return 0;}reload_inode_bitmap();cur=(cur-1)/8;while(bitbuf[cur]==255){if(cur==511)cur=0;else cur++;}while(bitbuf[cur]&con){con=con/2;flag++;}bitbuf[cur]=bitbuf[cur]+con;last_alloc_inode=cur*8+flag+1;update_inode_bitmap();super_block[0].bg_free_inodes_count--;update_group_desc();return last_alloc_inode;}//void remove_inode(unsigned short del_num){unsigned short tmp;tmp=(del_num-1)/8;reload_inode_bitmap();switch((del_num-1)%8)//更改block位图{case 0:bitbuf[tmp]=bitbuf[tmp]&127;break;case 1:bitbuf[tmp]=bitbuf[tmp]&191;break;case 2:bitbuf[tmp]=bitbuf[tmp]&223;break;case 3:bitbuf[tmp]=bitbuf[tmp]&239;break;case 4:bitbuf[tmp]=bitbuf[tmp]&247;break;case 5:bitbuf[tmp]=bitbuf[tmp]&251;break;case 6:bitbuf[tmp]=bitbuf[tmp]&253;break;case 7:bitbuf[tmp]=bitbuf[tmp]&254;break;}update_inode_bitmap();super_block[0].bg_free_inodes_count++;update_group_desc();}// dirvoid dir_prepare(unsigned short tmp,unsigned short len,int type) //新目录和文件初始化.and ..{reload_inode_entry(tmp);//得到新目录的节点入口地址if(type==2)//目录{inode_area[0].i_size=32;inode_area[0].i_blocks=1;inode_area[0].i_block[0]=alloc_block();dir[0].inode=tmp;dir[1].inode=current_dir;dir[0].name_len=len;dir[1].name_len=current_dirlen;dir[0].file_type=dir[1].file_type=2;for(type=2;type<32;type++)dir[type].inode=0;strcpy(dir[0].name,".");strcpy(dir[1].name,"..");update_dir(inode_area[0].i_block[0]);inode_area[0].i_mode=01006;//drwxrwxrwx:目录}else{inode_area[0].i_size=0;inode_area[0].i_blocks=0;inode_area[0].i_mode=0407;//drwxrwxrwx:文件}update_inode_entry(tmp);}//unsigned short reserch_file(char tmp[9],int file_type,unsigned short *inode_num,unsigned short *block_num,unsigned short *dir_num){ //查找文件并改写缓冲区里节点号,所在目录节点的数据块号(0~7)、目录项所在号unsigned short j,k;reload_inode_entry(current_dir);j=0;while(j<inode_area[0].i_blocks){reload_dir(inode_area[0].i_block[j]);k=0;while(k<32){if(!dir[k].inode||dir[k].file_type!=file_type||strcmp(dir[k].name,tmp))k++;else{*inode_num=dir[k].inode;*block_num=j;*dir_num=k;return 1;}}j++;}return 0;}//void cd(char tmp[9]){unsigned short i,j,k,flag;flag=reserch_file(tmp,2,&i,&j,&k);if(flag){current_dir=i;if(!strcmp(tmp,"..")&&dir[k-1].name_len){current_path[strlen(current_path)-dir[k-1].name_len-1]='\0';current_dirlen=dir[k].name_len;}else if(!strcmp(tmp,"."));else if(strcmp(tmp,"..")){current_dirlen=strlen(tmp);strcat(current_path,tmp);strcat(current_path,"/");}}else printf("The directory %s not exists!\n",tmp);}//void del(char tmp[9])unsigned short i,j,k,m,n,flag;m=0;flag=reserch_file(tmp,1,&i,&j,&k);if(flag){flag=0;while(fopen_table[flag]!=dir[k].inode&&flag<16)flag++;if(flag<16)fopen_table[flag]=0;reload_inode_entry(i);while(m<inode_area[0].i_blocks)remove_block(inode_area[0].i_block[m++]);inode_area[0].i_blocks=0;inode_area[0].i_size=0;remove_inode(i);reload_inode_entry(current_dir);dir[k].inode=0;//if(k!=0)dir[k-1].rec_len+=dir[k].rec_len ;update_dir(inode_area[0].i_block[j]);inode_area[0].i_size-=16;m=1;while(m<inode_area[i].i_blocks){flag=n=0;reload_dir(inode_area[0].i_block[m]);while(n<32){if(!dir[n].inode)flag++;n++;}if(flag==32){remove_block(inode_area[i].i_block[m]);inode_area[i].i_blocks--;while(m<inode_area[i].i_blocks)inode_area[i].i_block[m]=inode_area[i].i_block[++m];}}update_inode_entry(current_dir);}else printf("The file %s not exists!\n",tmp);}//void mkdir(char tmp[9],int type)unsigned short tmpno,i,j,k,flag;reload_inode_entry(current_dir); //获得当前目录的索引节点给inode_area[0]if(!reserch_file(tmp,type,&i,&j,&k)) //未找到同名文件{if(inode_area[0].i_size==4096) //目录项已满{printf("Directory has no room to be alloced!\n");return;}flag=1;if(inode_area[0].i_size!=inode_area[0].i_blocks*512)//目录中有某些个块中32个项未满{i=0;while(flag&&i<inode_area[0].i_blocks){reload_dir(inode_area[0].i_block[i]);j=0;while(j<32){if(dir[j].inode==0){flag=0;break;}j++;}i++;}tmpno=dir[j].inode=get_inode();dir[j].name_len=strlen(tmp);dir[j].file_type=type;strcpy(dir[j].name,tmp);update_dir(inode_area[0].i_block[i-1]);}else//全满{inode_area[0].i_block[inode_area[0].i_blocks]=alloc_block();inode_area[0].i_blocks++;reload_dir(inode_area[0].i_block[inode_area[0].i_blocks-1]);tmpno=dir[0].inode=get_inode();dir[0].name_len=strlen(tmp);dir[0].file_type=type;strcpy(dir[0].name,tmp);//初始化新块for(flag=1;flag<32;flag++)dir[flag].inode=0;update_dir(inode_area[0].i_block[inode_area[0].i_blocks-1]);}inode_area[0].i_size+=16;update_inode_entry(current_dir);dir_prepare(tmpno,strlen(tmp),type);}else //已经存在同名文件或目录{if(type==1)printf("File has already existed!\n");else printf("Directory has already existed!\n");}}//void rmdir(char tmp[9]){unsigned short i,j,k,flag;unsigned short m,n;if(!strcmp(tmp,"..")||!strcmp(tmp,".")){printf("The directory can not be deleted!\n");return;}flag=reserch_file(tmp,2,&i,&j,&k);if(flag){reload_inode_entry(dir[k].inode); //找到要删除的目录的节点并载入if(inode_area[0].i_size==32) //只有.and ..{inode_area[0].i_size=0;inode_area[0].i_blocks=0;//reload_dir(inode_area[0].i_block[0]);//dir[0].inode=0;//dir[1].inode=0;remove_block(inode_area[0].i_block[0]);reload_inode_entry(current_dir);//得到当前目录的节点并更改当前目录项remove_inode(dir[k].inode);dir[k].inode=0;update_dir(inode_area[0].i_block[j]);inode_area[0].i_size-=16;flag=0;m=1;while(flag<32&&m<inode_area[0].i_blocks){flag=n=0;reload_dir(inode_area[0].i_block[m]);while(n<32){if(!dir[n].inode)flag++;n++;}if(flag==32){remove_block(inode_area[0].i_block[m]);inode_area[0].i_blocks--;while(m<inode_area[0].i_blocks)inode_area[0].i_block[m]=inode_area[0].i_block[++m];}}update_inode_entry(current_dir);}else printf("Directory is not null!\n");}else printf("Directory to be deleted not exists!\n");}//void ls(){int i,j,k,tmpno,no;i=0;printf("items type mode size\n");reload_inode_entry(current_dir);while(i<inode_area[0].i_blocks){k=0;reload_dir(inode_area[0].i_block[i]);while(k<32){if(dir[k].inode){printf("%s",dir[k].name);if(dir[k].file_type==2){j=0;reload_inode_entry(dir[k].inode);if(!strcmp(dir[k].name,".."))while(j++<13)printf(" ");else if(!strcmp(dir[k].name,"."))while(j++<14)printf(" ");else while(j++<15-dir[k].name_len)printf(" ");printf("<DIR> ");switch(inode_area[0].i_mode&7){case 1:printf("____x");break;case 2:printf("__w__");break;case 3:printf("__w_x");break;case 4:printf("r____");break;case 5:printf("r___x");break;case 6:printf("r_w__");break;case 7:printf("r_w_x");break;}printf(" ----");}else if(dir[k].file_type==1){j=0;reload_inode_entry(dir[k].inode);while(j++<15-dir[k].name_len)printf(" ");printf("<FILE> ");switch(inode_area[0].i_mode&7){case 1:printf("____x");break;case 2:printf("__w__");break;case 3:printf("__w_x");break;case 4:printf("r____");break;case 5:printf("r___x");break;case 6:printf("r_w__");break;case 7:printf("r_w_x");break;}printf(" %d bytes ",inode_area[0].i_size);}printf("\n");}k++;reload_inode_entry(current_dir);}i++;}}// fileunsigned short search_file(unsigned short Ino)//在打开文件表中查找是否已打开文件{unsigned short fopen_table_point=0;while(fopen_table_point<16&&fopen_table[fopen_table_point++]!=Ino);if(fopen_table_point==16)return 0;return 1;}//void read_file(char tmp[9])//读文件{unsigned short flag,i,j,k;flag=reserch_file(tmp,1,&i,&j,&k); //返回文件目录项的信息if(flag){if(search_file(dir[k].inode)){reload_inode_entry(dir[k].inode);if(!(inode_area[0].i_mode&4))//i_mode:111b:读,写,执行{printf("The file %s can not be read!\n",tmp);return;}for(flag=0;flag<inode_area[0].i_blocks;flag++){reload_block(inode_area[0].i_block[flag]);Buffer[512]='\0';printf("%s",Buffer);}if(flag==0)printf("The file %s is empty!\n",tmp);else printf("\n");}else printf("The file %s has not been opened!\n",tmp);}else printf("The file %s not exists!\n",tmp);}void write_file(char tmp[9])//写文件{unsigned short flag,i,j,k,size=0,need_blocks;flag=reserch_file(tmp,1,&i,&j,&k);if(flag){if(search_file(dir[k].inode)){reload_inode_entry(dir[k].inode);if(!(inode_area[0].i_mode&2))//i_mode:111b:读,写,执行{printf("The file %s can not be writed!\n",tmp);return;}while(1){tempbuf[size]=getchar();if(tempbuf[size]=='#'){tempbuf[size]='\0';break;}if(size>=4096){printf("Sorry,the max size of a file is 4KB!\n");tempbuf[size]='\0';break;}size++;}need_blocks=strlen(tempbuf)/512;if(strlen(tempbuf)%512)need_blocks++;if(need_blocks<9){while(inode_area[0].i_blocks<need_blocks){inode_area[0].i_block[inode_area[0].i_blocks]=alloc_block();inode_area[0].i_blocks++;}j=0;while(j<need_blocks){if(j!=need_blocks-1){reload_block(inode_area[0].i_block[j]);memcpy(Buffer,tempbuf+j*BLOCK_SIZE,BLOCK_SIZE);update_block(inode_area[0].i_block[j]);}else{reload_block(inode_area[0].i_block[j]);memcpy(Buffer,tempbuf+j*BLOCK_SIZE,strlen(tempbuf)-j*BLOCK_SIZE);if(strlen(tempbuf)>inode_area[0].i_size){Buffer[strlen(tempbuf)-j*BLOCK_SIZE]='\0';inode_area[0].i_size=strlen(tempbuf);}update_block(inode_area[0].i_block[j]);}j++;}update_inode_entry(dir[k].inode);}else printf("Sorry,the max size of a file is 4KB!\n");}else printf("The file %s has not opened!\n",tmp);}else printf("The file %s does not exist!\n",tmp);}//void close_file(char tmp[9])//关闭文件{unsigned short flag,i,j,k;flag=reserch_file(tmp,1,&i,&j,&k);if(flag){if(search_file(dir[k].inode)){flag=0;while(fopen_table[flag]!=dir[k].inode)flag++;fopen_table[flag]=0;printf("File: %s! closed\n",tmp);}else printf("The file %s has not been opened!\n",tmp);}else printf("The file %s does not exist!\n",tmp);}void open_file(char tmp[9]){unsigned short flag,i,j,k;flag=reserch_file(tmp,1,&i,&j,&k);if(flag){if(search_file(dir[k].inode))printf("The file %s has opened!\n",tmp);else{flag=0;while(fopen_table[flag])flag++;fopen_table[flag]=dir[k].inode;printf("File %s! opened\n",tmp);}}else printf("The file %s does not exist!\n",tmp);}// formatvoid initialize_disk(){int i=0;printf("Creating the ext2 file system\n");printf("Please wait ");while(i<1){printf("... ");// sleep(1);i++;}printf("\n");last_alloc_inode=1;last_alloc_block=0;for(i=0;i<16;i++)fopen_table[i]=0;//清空缓冲表for(i=0;i<BLOCK_SIZE;i++)Buffer[i]=0;// 清空缓冲区,通过缓冲区清空文件,即清空磁盘fp=fopen("FS_zqw_zzw.txt","w+b");fseek(fp,DISK_START,SEEK_SET);for(i=0;i<4611;i++)fwrite(Buffer,BLOCK_SIZE,1,fp);//清空文件,即清空磁盘全部用0填充reload_group_desc();reload_inode_entry(1);reload_dir(0);strcpy(current_path,"[root@ /"); //该路径名strcpy(super_block[0].bg_volume_name,"EXT2FS"); //改卷名,初始化组描述符内容super_block[0].bg_block_bitmap=BLOCK_BITMAP;super_block[0].bg_inode_bitmap=INODE_BITMAP;super_block[0].bg_inode_table=INODE_TABLE;super_block[0].bg_free_blocks_count=4096;super_block[0].bg_free_inodes_count=4096;super_block[0].bg_used_dirs_count=0;// 初始化组描述符内容update_group_desc(); //更新组描述符内容reload_block_bitmap();reload_inode_bitmap();inode_area[0].i_mode=518;inode_area[0].i_blocks=0;inode_area[0].i_size=32;inode_area[0].i_atime=0;inode_area[0].i_ctime=0;inode_area[0].i_mtime=0;inode_area[0].i_dtime=0;inode_area[0].i_block[0]=alloc_block();inode_area[0].i_blocks++;current_dir=get_inode();update_inode_entry(current_dir);dir[0].inode=dir[1].inode=current_dir;dir[0].name_len=0;dir[1].name_len=0;dir[0].file_type=dir[1].file_type=2;//1:文件;2:目录strcpy(dir[0].name,".");strcpy(dir[1].name,"..");update_dir(inode_area[0].i_block[0]);printf("The ext2 file system has been installed!\n");}void initialize_memory(){int i=0;last_alloc_inode=1;last_alloc_block=0;for(i=0;i<16;i++)fopen_table[i]=0;strcpy(current_path,"[root@ /");current_dir=1;fp=fopen("FS_zqw_zzw.txt","r+b");if(fp==NULL){printf("The File system does not exist!\n");initialize_disk();return ;}reload_group_desc();}void format(){initialize_disk();initialize_memory();}void help(){printf(" ext文件系统模拟\n");printf(" 可以使用的命令: \n");printf(" 1.进入文件目录: cd+dir_name 7.创建文件目录: mkdir+dir_name \n");printf(" 2.创建文件: mkf+file_name 8.删除目录: rmdir+dir_name \n");printf(" 3.删除文件: rm+file_name 9.读取文件: read+file_name \n");printf(" 4.打开文件: open+file_name 10.写文件: write+file_name \n");printf(" 5.关闭文件: close+file_name 11.退出: quit \n");printf(" 6.列出项目: ls 12.查看帮助: help \n");printf(" 13.format disk : format \n");}// mainint main(char argc,char **argv){char command[10],temp[9];initialize_memory();printf("输入help查看帮助\n");while(1){printf("%s]#",current_path);scanf("%s",command);if(!strcmp(command,"cd")){scanf("%s",temp);cd(temp);}else if(!strcmp(command,"mkdir")) {scanf("%s",temp);mkdir(temp,2);}else if(!strcmp(command,"mkf")) {scanf("%s",temp);mkdir(temp,1);}else if(!strcmp(command,"rmdir")) {scanf("%s",temp);rmdir(temp);}else if(!strcmp(command,"rm")) {scanf("%s",temp);del(temp);}else if(!strcmp(command,"open")) {scanf("%s",temp);open_file(temp);}else if(!strcmp(command,"close")) {scanf("%s",temp);close_file(temp);}else if(!strcmp(command,"read")) {scanf("%s",temp);read_file(temp);}else if(!strcmp(command,"write")) {scanf("%s",temp);write_file(temp);}else if(!strcmp(command,"ls"))ls();else if(!strcmp(command,"format")){char tempch;printf("Format will erase all the data in the Disk\n");printf("Are you sure?y/n:\n");scanf(" %c",&tempch);if(tempch=='Y'||tempch=='y'){fclose(fp);initialize_disk();}elseprintf("Format Disk canceled\n");}else if(!strcmp(command,"help"))help();else if(!strcmp(command,"quit"))break;else printf("No this Command,Please check!\n");}return 0;}。