西工大计算机操作系统实验报告OS2

合集下载

计算机操作系统实验报告

计算机操作系统实验报告

计算机操作系统实验报告一、实验目的本次实验的主要目的是深入了解计算机操作系统的工作原理和功能,通过实际操作和观察,掌握操作系统的基本概念和常用命令,提高对计算机系统的管理和控制能力。

二、实验环境1、操作系统:Windows 10 专业版2、硬件配置:Intel Core i5 处理器,8GB 内存,256GB 固态硬盘三、实验内容1、进程管理通过任务管理器观察系统中正在运行的进程,包括进程的名称、PID(进程标识符)、CPU 使用率、内存使用情况等。

尝试结束一些非关键进程,观察系统的反应。

2、内存管理使用系统自带的性能监视器查看内存的使用情况,包括物理内存、虚拟内存的总量、已使用量和可用量。

运行一些大型程序,观察内存的分配和释放过程。

3、文件管理创建、复制、移动、删除文件和文件夹,观察文件系统的操作效果。

查看文件和文件夹的属性,包括大小、创建时间、修改时间、访问权限等。

4、设备管理查看设备管理器中硬件设备的状态,包括是否正常工作、驱动程序的版本等。

尝试更新一些设备的驱动程序,观察设备性能的变化。

四、实验步骤及结果1、进程管理打开任务管理器,可以看到系统中正在运行的进程列表。

进程按照名称、PID、CPU 使用率、内存使用情况等进行排序。

例如,系统进程“System”和“svchostexe”通常占用一定的 CPU 和内存资源。

尝试结束一些非关键进程,如某些后台运行的软件进程。

在结束进程时,系统会提示可能会导致相关程序无法正常运行,确认后结束进程。

部分进程结束后,对应的程序会关闭,系统的资源占用也会相应减少。

2、内存管理打开性能监视器,在“内存”选项中可以直观地看到物理内存和虚拟内存的使用情况。

当运行大型程序时,如游戏或图形处理软件,内存的使用量会显著增加。

随着程序的关闭,已使用的内存会逐渐释放,可用内存量会回升。

3、文件管理在文件资源管理器中进行文件和文件夹的操作。

创建新文件和文件夹时,可以指定名称、类型和存储位置。

操作系统实验实验报告

操作系统实验实验报告

操作系统实验实验报告一、实验目的操作系统是计算机系统中最为关键的核心软件,它管理着计算机的硬件资源和软件资源,为用户提供了一个方便、高效、稳定的工作环境。

本次操作系统实验的目的在于通过实际操作和实践,深入理解操作系统的基本原理和核心概念,掌握操作系统的基本功能和操作方法,提高对操作系统的认识和应用能力。

二、实验环境本次实验使用的操作系统为 Windows 10 专业版,开发工具为Visual Studio 2019,编程语言为 C 和 C++。

实验硬件环境为一台配备Intel Core i7 处理器、16GB 内存、512GB SSD 硬盘的个人计算机。

三、实验内容(一)进程管理实验1、进程创建与终止通过编程实现创建新的进程,并在完成任务后终止进程。

在实验中,我们使用了 Windows API 函数 CreateProcess 和 TerminateProcess 来完成进程的创建和终止操作。

通过观察进程的创建和终止过程,深入理解了进程的生命周期和状态转换。

2、进程同步与互斥为了实现进程之间的同步与互斥,我们使用了信号量、互斥量等同步对象。

通过编写多线程程序,模拟了多个进程对共享资源的访问,实现了对共享资源的互斥访问和同步操作。

在实验中,我们深刻体会到了进程同步与互斥的重要性,以及不正确的同步操作可能导致的死锁等问题。

(二)内存管理实验1、内存分配与释放使用 Windows API 函数 VirtualAlloc 和 VirtualFree 进行内存的分配和释放操作。

通过实验,了解了内存分配的不同方式(如堆分配、栈分配等)以及内存释放的时机和方法,掌握了内存管理的基本原理和操作技巧。

2、内存分页与分段通过编程模拟内存的分页和分段管理机制,了解了内存分页和分段的基本原理和实现方法。

在实验中,我们实现了简单的内存分页和分段算法,对内存的地址转换和页面置换等过程有了更深入的理解。

(三)文件系统实验1、文件操作使用 Windows API 函数 CreateFile、ReadFile、WriteFile 等进行文件的创建、读取和写入操作。

操作系统实验二实验报告

操作系统实验二实验报告

操作系统实验二实验报告一、实验目的本次操作系统实验二的主要目的是深入理解和掌握进程管理的相关概念和技术,包括进程的创建、执行、同步和通信。

通过实际编程和实验操作,提高对操作系统原理的认识,培养解决实际问题的能力。

二、实验环境本次实验使用的操作系统为 Windows 10,编程环境为 Visual Studio 2019。

三、实验内容及步骤(一)进程创建实验1、首先,创建一个新的 C++项目。

2、在项目中,使用 Windows API 函数`CreateProcess`来创建一个新的进程。

3、为新进程指定可执行文件的路径、命令行参数、进程属性等。

4、编写代码来等待新进程的结束,并获取其退出代码。

(二)进程同步实验1、设计一个生产者消费者问题的模型。

2、使用信号量来实现生产者和消费者进程之间的同步。

3、生产者进程不断生成数据并放入共享缓冲区,当缓冲区已满时等待。

4、消费者进程从共享缓冲区中取出数据进行处理,当缓冲区为空时等待。

(三)进程通信实验1、选择使用管道来实现进程之间的通信。

2、创建一个匿名管道,父进程和子进程分别读写管道的两端。

3、父进程向管道写入数据,子进程从管道读取数据并进行处理。

四、实验结果及分析(一)进程创建实验结果成功创建了新的进程,并能够获取到其退出代码。

通过观察进程的创建和执行过程,加深了对进程概念的理解。

(二)进程同步实验结果通过使用信号量,生产者和消费者进程能够正确地进行同步,避免了缓冲区的溢出和数据的丢失。

分析结果表明,信号量机制有效地解决了进程之间的资源竞争和协调问题。

(三)进程通信实验结果通过管道实现了父进程和子进程之间的数据通信。

数据能够准确地在进程之间传递,验证了管道通信的有效性。

五、遇到的问题及解决方法(一)在进程创建实验中,遇到了参数设置不正确导致进程创建失败的问题。

通过仔细查阅文档和调试,最终正确设置了参数,成功创建了进程。

(二)在进程同步实验中,出现了信号量使用不当导致死锁的情况。

《操作系统》实验报告

《操作系统》实验报告

《操作系统》实验报告一、实验目的操作系统是计算机系统中最为关键的组成部分之一,本次实验的主要目的是深入理解操作系统的基本原理和功能,通过实际操作和观察,熟悉操作系统的核心概念,包括进程管理、内存管理、文件系统和设备管理等,提高对操作系统的实际应用能力和问题解决能力。

二、实验环境本次实验在以下环境中进行:操作系统:Windows 10开发工具:Visual Studio 2019编程语言:C++三、实验内容1、进程管理实验进程是操作系统中最基本的执行单元。

在这个实验中,我们使用C++编写程序来创建和管理进程。

通过观察进程的创建、执行和结束过程,理解进程的状态转换和资源分配。

首先,我们编写了一个简单的程序,创建了多个子进程,并通过进程标识符(PID)来跟踪它们的运行状态。

然后,使用等待函数来等待子进程的结束,并获取其返回值。

在实验过程中,我们发现进程的创建和销毁需要消耗一定的系统资源,而且进程之间的同步和通信需要谨慎处理,以避免出现死锁和竞争条件等问题。

2、内存管理实验内存管理是操作系统的核心功能之一,它直接影响系统的性能和稳定性。

在这个实验中,我们研究了动态内存分配和释放的机制。

使用 C++中的 new 和 delete 操作符来分配和释放内存。

通过观察内存使用情况和内存泄漏检测工具,了解了内存分配的效率和可能出现的内存泄漏问题。

同时,我们还探讨了内存分页和分段的概念,以及虚拟内存的工作原理。

通过模拟内存访问过程,理解了页表的作用和地址转换的过程。

3、文件系统实验文件系统是操作系统用于管理文件和目录的机制。

在这个实验中,我们对文件的创建、读写和删除进行了操作。

使用 C++的文件流操作来实现对文件的读写。

通过创建不同类型的文件(文本文件和二进制文件),并对其进行读写操作,熟悉了文件的打开模式和读写方式。

此外,还研究了文件的权限设置和目录的管理,了解了如何保护文件的安全性和组织文件的结构。

4、设备管理实验设备管理是操作系统与外部设备进行交互的桥梁。

计算机操作系统实验报告

计算机操作系统实验报告

计算机操作系统实验报告一、实验目的本次计算机操作系统实验的主要目的是深入了解操作系统的工作原理和功能,通过实际操作和观察,增强对操作系统概念的理解,提高解决实际问题的能力。

二、实验环境1、操作系统:Windows 10 专业版2、开发工具:Visual Studio 20193、编程语言:C++三、实验内容1、进程管理实验创建多个进程,并观察它们的执行顺序和资源占用情况。

使用进程控制块(PCB)来跟踪进程的状态变化,如就绪、运行、阻塞等。

2、内存管理实验模拟内存分配和回收算法,如首次适应算法、最佳适应算法和最坏适应算法。

观察不同算法在内存利用率和分配效率方面的表现。

3、文件系统实验创建、读取、写入和删除文件,了解文件的操作流程。

研究文件的存储结构和目录管理方式。

4、线程同步与互斥实验使用互斥锁和信号量来实现线程之间的同步和互斥操作。

观察在多线程环境下资源竞争和同步的效果。

四、实验步骤1、进程管理实验步骤编写 C++程序,使用系统调用创建多个进程。

在每个进程中输出进程的标识符和当前执行时间。

通过观察控制台输出,分析进程的执行顺序和资源占用情况。

2、内存管理实验步骤实现不同的内存分配算法,并在程序中模拟内存请求和释放的过程。

记录每次内存分配和回收的结果,计算内存利用率和分配时间。

3、文件系统实验步骤使用文件操作函数创建文件,并写入一些数据。

读取文件中的数据,并将其输出到控制台。

删除文件,观察文件系统的变化。

4、线程同步与互斥实验步骤创建多个线程,共享一些公共资源。

在访问公共资源的代码段前使用互斥锁或信号量进行同步控制。

观察线程的执行结果,确保资源的正确访问和修改。

五、实验结果与分析1、进程管理实验结果与分析实验结果显示,进程的执行顺序是不确定的,取决于操作系统的调度策略和进程的优先级。

资源占用情况也因进程的不同而有所差异,一些进程可能占用较多的 CPU 时间和内存,而另一些则相对较少。

2、内存管理实验结果与分析首次适应算法在分配速度上较快,但容易产生内存碎片。

操作系统实验报告实验二

操作系统实验报告实验二

操作系统实验报告实验二一、实验目的本次操作系统实验二的目的在于深入理解和掌握操作系统中的进程管理和进程调度相关知识,通过实际的编程和实验操作,观察和分析不同进程调度算法的性能和效果,提高对操作系统核心概念的理解和应用能力。

二、实验环境本次实验在 Windows 10 操作系统下进行,使用 Visual Studio 2019作为编程工具。

实验中涉及的编程语言为 C++。

三、实验内容(一)进程创建与控制编写程序实现创建多个进程,并通过进程控制原语(如创建、等待、终止等)对进程进行管理和控制。

(二)进程调度算法实现1、先来先服务(FCFS)调度算法按照进程到达的先后顺序进行调度,先到达的进程先获得 CPU 资源进行执行。

2、短作业优先(SJF)调度算法优先调度执行时间短的进程,以减少平均等待时间。

3、时间片轮转(RR)调度算法将 CPU 时间划分为固定大小的时间片,每个进程在一个时间片内执行,时间片结束后切换到下一个进程。

(三)性能评估指标1、平均等待时间所有进程等待时间的总和除以进程数量。

2、平均周转时间所有进程周转时间的总和除以进程数量。

周转时间为进程从提交到完成的时间间隔。

四、实验步骤(一)进程创建与控制1、定义进程结构体,包含进程 ID、到达时间、执行时间等信息。

2、使用系统调用或库函数创建进程。

3、在父进程中通过等待函数等待子进程结束,并获取子进程的返回状态。

(二)进程调度算法实现1、先来先服务(FCFS)调度算法按照进程到达时间的先后顺序将进程放入就绪队列。

从就绪队列中取出第一个进程进行调度执行。

2、短作业优先(SJF)调度算法计算每个进程的执行时间。

按照执行时间从小到大的顺序将进程放入就绪队列。

从就绪队列中取出执行时间最短的进程进行调度执行。

3、时间片轮转(RR)调度算法将进程按照到达时间先后顺序放入就绪队列。

为每个进程分配一个时间片,当时间片用完后,将进程放入就绪队列尾部,重新调度下一个进程。

OS实验2

OS实验2

实验2:文件部分系统调用1、实验目的(1)文件部分系统调用;(2)通过系统调用实现文件的顺序读取,文件顺序写入,文件的追加,文件随机存取。

2、实现设备一台装有Windows操作系统和Linux机系统的微机或服务器。

3、实验方法与注意事项1)由于是以root用户工作的,权力很大,请不要在系统内做对系统或对其他用户不安全的事情。

2)要求每个同学登录后系统后,要在自己的家目录内容以自己(汉语拼音)名字,使用mkdir命令创建一个子目录。

以后所有工作都要在自己的目录内进行。

3)认真编写实验报告。

4、实验过程实验1:文件的创建与(追加)写入(1)令文件名为app.c,使用vi编辑器,编辑并输入此文件;(2)调通该程序,实现文件的创建、追加与顺序写入。

(3)编译方法: cc –o app app.c(4)执行办法:./app(5)观察文件内容:cat myfile(6)若编译有警告提示,请修改程序,使不再警告。

实验2:文件复制(1)令文件名为copy.c,使用vi编辑器,编辑并输入此文件;(2)调通该程序,实现文件的创建、追加与顺序写入;(3)编译方法: cc –o copy copy.c(4)执行办法: ./copy ifile ofile(5)搞清楚main(int argc,char *argv[])中argc和argv的意义及用法;(6)根据ifile和ofile文件的类属和权限等进行测试,以验证程序的正确性;(7)对于正常情况,观察文件内容,验证程序执行的结果。

或可使用cmp ifile ofile 以比较ifile与ofile的异同;(8)若编译有警告提示,请修改程序,使不再警告。

可以使用ls –l ifile ofile查看两个文件的大小,也可使用cmp ifile ofile 比较两者差别,也可直接使用cat命令查看文件的内容。

实验3:文件删除(1)令文件名为del.c,使用vi编辑器,编辑并输入此文件。

计算机操作系统实验_操作系统引导

计算机操作系统实验_操作系统引导

西北工业大学操作系统实验实验报告一、实验目的熟悉GeekOS实验环境。

二、实验要求编译运行操作系统的启动代码。

三、实验过程及结果1、编写第一个“操作系统”,代码如下:org 07c00hmov ax,csmov ds,axmov es,axcall DispStrjmp $DispStr:mov ax,BootMessagemov bp,axmov cx,16mov ax,01301hmov bx,00aehmov dl,0int 10hretBootMessage: db "hello,OS world!"times 510-($-$$) db 0dw 0xaa55结果如图:修改boot.asm,修改文字颜色,代码如下:org 07c00hmov ax,csmov ds,axmov es,axcall DispStrjmp $DispStr:mov ax,BootMessagemov bp,axmov cx,16mov ax,01301hmov bx,00aeh //在此处修改BL的值,可以修改颜色mov dl,0int 10hretBootMessage: db "hello,OS world! "times 510-($-$$) db 0dw 0xaa55结果如图:2.在bochs中运行geek OS,结果如图:四、实验分析思考:引导扇区的标志是0x55AA,为何代码中写入的却是 dw 0xAA55?答:因为存储时低位在前,高位在后,所以代码中高低位反过来写。

五、所遇问题及解决方法答:实验过程中,最大的困难就是理解geek OS的代码。

一个原因是我们没有学过有关汇编的知识,导致代码中有关汇编的部分一头雾水,难以理解;另一方面是之前自己接触的源码比较少,第一次见到geek OS这么大的工程代码,感觉理解起来很困难,不过,在老师花费了几个小时的讲解下,我最终还是勉强理解了一部分。

西北工业大学_计算机系统基础_实验报告_第2次

西北工业大学_计算机系统基础_实验报告_第2次

计算机系统基础实验课第二次实验报告对二进制炸弹求解过程的详细描述首先使用objdump命令对bomb程序进行反汇编,并将汇编代码输出到asm.txt中。

阶段一、字符串比较打开asm.txt文件,搜索到phase_1函数,可以看到以下代码。

08048b33 <phase_1>:8048b33: 83 ec 14 sub $0x14,%esp8048b36: 68 7c a0 04 08 push $0x804a07c8048b3b: ff 74 24 1c pushl 0x1c(%esp)8048b3f: e8 3e 05 00 00 call 8049082 <strings_not_equal>8048b44: 83 c4 10 add $0x10,%esp8048b47: 85 c0 test %eax,%eax8048b49: 74 05 je 8048b50 <phase_1+0x1d>8048b4b: e8 29 06 00 00 call 8049179 <explode_bomb>8048b50: 83 c4 0c add $0xc,%esp8048b53: c3 ret可以看出,用户输入字串指针保存在0x1c(%esp),然后调用<strings_not_equal>,待<strings_not_equal>返回后,测试返回值,若equal则进入下一phase,否则<explode_bomb>,从<strings_not_equal>可知该函数用于比较两函数的值,因此需要两个字串作为输入,上面代码中, pushl 0x1c(%esp)用于传递用户字串指针,则push $0x804a07c自然是传递比较字串的指针了。

打开gdb,x/s 0x80497c0, 可以直接查看到该指针指向的子符串:所以第一个炸弹的拆弹指令为:I turned the moon into something I call a Death Star.阶段二、循环在asm.txt文件中可以找到phase_2函数代码如下:08048b54 <phase_2>:8048b54: 56 push %esi8048b55: 53 push %ebx8048b56: 83 ec 2c sub $0x2c,%esp8048b59: 65 a1 14 00 00 00 mov %gs:0x14,%eax8048b5f: 89 44 24 24 mov %eax,0x24(%esp)8048b63: 31 c0 xor %eax,%eax8048b65: 8d 44 24 0c lea 0xc(%esp),%eax8048b69: 50 push %eax8048b6a: ff 74 24 3c pushl 0x3c(%esp)8048b6e: e8 2b 06 00 00 call 804919e <read_six_numbers>8048b73: 83 c4 10 add $0x10,%esp8048b76: 83 7c 24 04 01 cmpl $0x1,0x4(%esp)8048b7b: 74 05 je 8048b82 <phase_2+0x2e>8048b7d: e8 f7 05 00 00 call 8049179 <explode_bomb>8048b82: 8d 5c 24 04 lea 0x4(%esp),%ebx8048b86: 8d 74 24 18 lea 0x18(%esp),%esi8048b8a: 8b 03 mov (%ebx),%eax8048b8c: 01 c0 add %eax,%eax8048b8e: 39 43 04 cmp %eax,0x4(%ebx)8048b91: 74 05 je 8048b98 <phase_2+0x44>8048b93: e8 e1 05 00 00 call 8049179 <explode_bomb>8048b98: 83 c3 04 add $0x4,%ebx8048b9b: 39 f3 cmp %esi,%ebx8048b9d: 75 eb jne 8048b8a <phase_2+0x36>8048b9f: 8b 44 24 1c mov 0x1c(%esp),%eax8048ba3: 65 33 05 14 00 00 00 xor %gs:0x14,%eax8048baa: 74 05 je 8048bb1 <phase_2+0x5d>8048bac: e8 df fb ff ff call 8048790 <__stack_chk_fail@plt>8048bb1: 83 c4 24 add $0x24,%esp8048bb4: 5b pop %ebx8048bb5: 5e pop %esi8048bb6: c3 ret根据call 804919e <read_six_numbers>可以推测题目要求是输入六个数字。

操作系统课内实验报告

操作系统课内实验报告

西安交通大学实验报告操作系统实验报告刘烜乐享科技计算机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()”和“编程调用自己创建的系统调用”进一步掌握创建和调用系统调用的方法。

计算机操作系统实验_运行用户态程序

计算机操作系统实验_运行用户态程序

西北工业大学操作系统实验实验报告一、实验目的掌握在GeekOS系统用户态模式下加载并运行可执行程序的方法。

二、实验要求1. 按照实验讲义P127页中的设计要求,实现在用户态模式下加载并运行可执行程序的代码,给出关键函数的代码以及实验结果。

三、实验过程及结果答:核心函数代码如下:================== user.c ===============//产生一个进程(用户态)int Spawn(const char *program, const char *command, struct Kernel_Thread **pThread) {//TODO("Spawn a process by reading an executable from a filesystem");int rc;char *exeFileData = 0;ulong_t exeFileLength;struct User_Context *userContext = 0;struct Kernel_Thread *process = 0;struct Exe_Format exeFormat;if ((rc = Read_Fully(program, (void**) &exeFileData, &exeFileLength)) != 0 ){Print("Failed to Read File %s!\n", program);goto fail;}if((rc = Parse_ELF_Executable(exeFileData, exeFileLength, &exeFormat)) != 0 ){Print("Failed to Parse ELF File!\n");goto fail;}if((rc = Load_User_Program(exeFileData, exeFileLength, &exeFormat, command, &userContext)) != 0){Print("Failed to Load User Program!\n");goto fail;}//在堆分配方式下释放内存并再次初始化exeFileDataFree(exeFileData);exeFileData = 0;/* 开始用户进程,调用Start_User_Thread函数创建一个进程并使其进入准备运行队列*/ process = Start_User_Thread(userContext, false);if (process != 0) {KASSERT(process->refCount == 2);/* 返回核心进程的指针*/*pThread = process;rc = process->pid;//记录当前进程的ID}elserc = ENOMEM;return rc;fail: //如果新进程创建失败则注销User_Context对象if (exeFileData != 0)Free(exeFileData);//释放内存if (userContext != 0)Destroy_User_Context(userContext);//销毁进程对象return rc;}-------------------------------------//切换至用户上下文void Switch_To_User_Context(struct Kernel_Thread* kthread, struct Interrupt_State* state){static struct User_Context* s_currentUserContext; /* last user context used *///extern int userDebug;struct User_Context* userContext = kthread->userContext;KASSERT(!Interrupts_Enabled());if (userContext == 0) { //userContext为0表示此进程为核心态进程就不用切换地址空间return;}if (userContext != s_currentUserContext) {ulong_t esp0;//if (userDebug) Print("A[%p]\n", kthread);Switch_To_Address_Space(userContext);//为用户态进程时则切换地址空间esp0 = ((ulong_t) kthread->stackPage) + PAGE_SIZE;//if (userDebug)// Print("S[%lx]\n", esp0);/* 新进程的核心栈. */Set_Kernel_Stack_Pointer(esp0);//设置内核堆栈指针/* New user context is active */s_currentUserContext = userContext;}}================== elf.c ====================int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength, struct Exe_Format *exeFormat){int i;elfHeader *head=(elfHeader*)exeFileData;programHeader *proHeader=(programHeader *)(exeFileData+head->phoff);KASSERT(exeFileData!=NULL);KASSERT(exeFileLength>head->ehsize+head->phentsize*head->phnum);KASSERT(head->entry%4==0);exeFormat->numSegments=head->phnum;exeFormat->entryAddr=head->entry;for(i=0;i<head->phnum;i++){exeFormat->segmentList[i].offsetInFile=proHeader->offset;exeFormat->segmentList[i].lengthInFile=proHeader->fileSize;exeFormat->segmentList[i].startAddress=proHeader->vaddr;exeFormat->segmentList[i].sizeInMemory=proHeader->memSize;exeFormat->segmentList[i].protFlags=proHeader->flags;proHeader++;}return 0;}=================== userseg.c ===================//需在此文件各函数前增加一个函数,此函数的功能是按给定的大小创建一个用户级进程上下文,具体实现如下://函数功能:按给定的大小创建一个用户级进程上下文static struct User_Context* Create_User_Context(ulong_t size){struct User_Context * UserContext;size = Round_Up_To_Page(size);UserContext = (struct User_Context *)Malloc(sizeof(struct User_Context));if (UserContext != 0)UserContext->memory = Malloc(size);//为核心态进程elsegoto fail;//内存为空if (0 == UserContext->memory)goto fail;memset(UserContext->memory, '\0', size);UserContext->size = size;//以下为用户态进程创建LDT(段描述符表)//新建一个LDT描述符UserContext->ldtDescriptor = Allocate_Segment_Descriptor();if (0 == UserContext->ldtDescriptor)goto fail;//初始化段描述符Init_LDT_Descriptor(UserContext->ldtDescriptor, UserContext->ldt, NUM_USER_LDT_ENTRIES);//新建一个LDT选择子UserContext->ldtSelector = Selector(KERNEL_PRIVILEGE, true, Get_Descriptor_Index(UserContext->ldtDescriptor));//新建一个文本段描述符Init_Code_Segment_Descriptor(&UserContext->ldt[0],(ulong_t) UserContext->memory,size / PAGE_SIZE,USER_PRIVILEGE);//新建一个数据段Init_Data_Segment_Descriptor(&UserContext->ldt[1],(ulong_t) UserContext->memory,size / PAGE_SIZE,USER_PRIVILEGE);//新建数据段和文本段选择子UserContext->csSelector = Selector(USER_PRIVILEGE, false, 0);UserContext->dsSelector = Selector(USER_PRIVILEGE, false, 1);//将引用数清0UserContext->refCount = 0;return UserContext;fail:if (UserContext != 0){if (UserContext->memory != 0){Free(UserContext->memory);}Free(UserContext);}return 0;}--------------------------------------------//摧毁用户上下文void Destroy_User_Context(struct User_Context* userContext){//TODO("Destroy a User_Context");//释放占用的LDTFree_Segment_Descriptor(userContext->ldtDescriptor);userContext->ldtDescriptor=0;//释放内存空间Free(userContext->memory);userContext->memory=0;//释放userContext本身占用的内存Free(userContext);userContext=0;}----------------------------------------------int Load_User_Program(char *exeFileData,ulong_t exeFileLength,struct Exe_Format *exeFormat,const char *command,struct User_Context **pUserContext){//TODO("Load a user executable into a user memory space using segmentation");int i;ulong_t maxva = 0;//要分配的最大内存空间unsigned numArgs;//进程数目ulong_t argBlockSize;//参数块的大小ulong_t size, argBlockAddr;//参数块地址struct User_Context *userContext = 0;//计算用户态进程所需的最大内存空间for (i = 0; i < exeFormat->numSegments; ++i) {//elf.hstruct Exe_Segment *segment = &exeFormat->segmentList[i];ulong_t topva = segment->startAddress + segment->sizeInMemory; /* FIXME: range check */if (topva > maxva)maxva = topva;}Get_Argument_Block_Size(command, &numArgs, &argBlockSize);//获取参数块信息size = Round_Up_To_Page(maxva) + DEFAULT_USER_STACK_SIZE;argBlockAddr = size;size += argBlockSize;userContext = Create_User_Context(size);//按相应大小创建一个进程if (userContext == 0)//如果为核心态进程return -1;for (i = 0; i < exeFormat->numSegments; ++i) {struct Exe_Segment *segment = &exeFormat->segmentList[i];//根据段信息将用户程序中的各段内容复制到分配的用户内存空间memcpy(userContext->memory + segment->startAddress, exeFileData + segment->offsetInFile,segment->lengthInFile);}//格式化参数块Format_Argument_Block(userContext->memory + argBlockAddr, numArgs, argBlockAddr, command);//初始化数据段,堆栈段及代码段信息userContext->entryAddr = exeFormat->entryAddr;userContext->argBlockAddr = argBlockAddr;userContext->stackPointerAddr = argBlockAddr;//将初始化完毕的User_Context赋给*pUserContext*pUserContext = userContext;return 0;//成功}----------------------------------------------//将用户态的进程复制到内核缓冲区bool Copy_From_User(void* destInKernel, ulong_t srcInUser, ulong_t bufSize){struct User_Context * UserContext = g_currentThread->userContext;//--: check if memory if validatedif (!Validate_User_Memory(UserContext,srcInUser, bufSize))return false;memcpy(destInKernel, UserContext->memory + srcInUser, bufSize);return true;}-----------------------------------------//将内核态的进程复制到用户态bool Copy_To_User(ulong_t destInUser, void* srcInKernel, ulong_t bufSize){struct User_Context * UserContext = g_currentThread->userContext;if (!Validate_User_Memory(UserContext, destInUser, bufSize))return false;memcpy(UserContext->memory + destInUser, srcInKernel, bufSize);return true;}----------------------------------------//切换到用户地址空间void Switch_To_Address_Space(struct User_Context *userContext){ushort_t ldtSelector= userContext->ldtSelector;/* Switch to the LDT of the new user context */__asm__ __volatile__ ("lldt %0"::"a"(ldtSelector));}================= kthread.c ===============添加头文件#include <geekos/user.h>----------------------------------//创建一个用户进程/*static*/ void Setup_User_Thread(struct Kernel_Thread* kthread, struct User_Context* userContext){ulong_t eflags = EFLAGS_IF;unsigned csSelector=userContext->csSelector;//CS选择子unsigned dsSelector=userContext->dsSelector;//DS选择子Attach_User_Context(kthread, userContext);//初始化用户态进程堆栈,使之看上去像刚被中断运行一样//分别调用Push函数将以下数据压入堆栈Push(kthread, dsSelector); //数据选择子Push(kthread, userContext->stackPointerAddr); //堆栈指针Push(kthread, eflags); //EflagsPush(kthread, csSelector); //文本选择子Push(kthread, userContext->entryAddr); //程序计数器Push(kthread, 0); //错误代码(0)Push(kthread, 0); //中断号(0)//初始化通用寄存单元,将ESI用户传递参数块地址Push(kthread, 0); /* eax */Push(kthread, 0); /* ebx */Push(kthread, 0); /* edx */Push(kthread, 0); /* edx */Push(kthread, userContext->argBlockAddr); /* esi */Push(kthread, 0); /* edi */Push(kthread, 0); /* ebp *///初始化数据段寄存单元Push(kthread, dsSelector); /* ds */Push(kthread, dsSelector); /* es */Push(kthread, dsSelector); /* fs */Push(kthread, dsSelector); /* gs */}//开始用户进程struct Kernel_Thread* Start_User_Thread(struct User_Context* userContext, bool detached) {struct Kernel_Thread* kthread = Create_Thread(PRIORITY_USER, detached);if (kthread != 0){Setup_User_Thread(kthread, userContext);Make_Runnable_Atomic(kthread);}return kthread;}================ syscall.c =================//需在此文件别的函数前增加一个函数,函数名为Copy_User_String,它被函数Sys_PrintString调用,具体实现如下:static int Copy_User_String(ulong_t uaddr, ulong_t len, ulong_t maxLen, char **pStr) { int rc = 0;char *str;if (len > maxLen){ //超过最大长度return EINV ALID;}str = (char*) Malloc(len+1); //为字符串分配空间if (0 == str){rc = ENOMEM;goto fail;}if (!Copy_From_User(str, uaddr, len)){ //从用户空间中复制数据rc = EINV ALID;Free(str);goto fail;}str[len] = '\0';//成功*pStr = str;fail:return rc;}-----------------------------------------static int Sys_Exit(struct Interrupt_State* state){Exit(state->ebx);}-----------------------------------------static int Sys_PrintString(struct Interrupt_State* state){int rc = 0;//返回值uint_t length = state->ecx;//字符串长度uchar_t* buf = 0;if (length > 0) {if ((rc = Copy_User_String(state->ebx, length, 1023, (char**) &buf)) != 0) goto done;Put_Buf(buf, length);}done:if (buf != 0)Free(buf);return rc;}----------------------------------------------static int Sys_GetKey(struct Interrupt_State* state){return Wait_For_Key(); //返回按键码keyboard.c/Wait_For_Key()}---------------------------------------------static int Sys_SetAttr(struct Interrupt_State* state){Set_Current_Attr((uchar_t) state->ebx);return 0;}---------------------------------------------static int Sys_GetCursor(struct Interrupt_State* state){int row, col;Get_Cursor(&row, &col);if (!Copy_To_User(state->ebx, &row, sizeof(int)) ||!Copy_To_User(state->ecx, &col, sizeof(int)))return -1;return 0;}-----------------------------------------------static int Sys_PutCursor(struct Interrupt_State* state){return Put_Cursor(state->ebx, state->ecx) ? 0 : -1;}-----------------------------------------------static int Sys_Spawn(struct Interrupt_State* state){int rc; //函数返回值char *program = 0; //进程名称char *command = 0; //用户命令struct Kernel_Thread *process;if ((rc = Copy_User_String(state->ebx, state->ecx, VFS_MAX_PATH_LEN, &program)) != 0){goto fail;}if(rc = Copy_User_String(state->edx, state->esi, 1023, &command)) != 0){//从用户空间复制用户命令goto fail;}Enable_Interrupts(); //开中断rc = Spawn(program, command, &process);//得到进程名称和用户命令后便可生成一个新进程if (rc == 0) {//若成功则返回新进程ID号KASSERT(process != 0);rc = process->pid;}Disable_Interrupts();//关中断fail://返回小于0的错误代码if (program != 0)Free(program);if (command != 0)Free(command);return rc;}-----------------------------------------static int Sys_Wait(struct Interrupt_State* state){ //TODO("Wait system call");int exitCode;struct Kernel_Thread *kthread = Lookup_Thread(state->ebx);if (kthread == 0)return -12;Enable_Interrupts();exitCode = Join(kthread);Disable_Interrupts();return exitCode;}---------------------------------------static int Sys_GetPID(struct Interrupt_State* state){ //TODO("GetPID system call");return g_currentThread->pid;}================= main.c ==================static void Spawn_Init_Process(void){ //TODO("Spawn the init process");struct Kernel_Thread *pThread;Spawn("/c/shell.exe","/c/shell.exe",&pThread);}实验结果如图所示:原理:Geekos 提供了一个简单的shell,保存在PFAT文件系统内,所以geekos 系统启动后,启动shell程序/c/shell.exe运行,将/c/shell.exe作为可执行文件传递给spawn函数的program参数,创建第一个用户态进程,然后由它来创建其他进程。

计算机操作系统实验报告

计算机操作系统实验报告

计算机操作系统实验报告计算机操作系统实验报告引言:计算机操作系统作为计算机系统的核心组成部分,承担着管理和控制计算机硬件资源的重要任务。

通过实验,我们可以更好地理解操作系统的工作原理和功能,掌握操作系统的基本操作和管理技巧。

本文将结合实验结果,对操作系统实验进行总结和分析。

实验一:操作系统安装与配置在这个实验中,我们学习了操作系统的安装和配置过程。

通过选择合适的操作系统版本、设置分区和文件系统等步骤,成功地安装了操作系统。

同时,我们还学习了如何进行系统配置,包括网络设置、用户管理和软件安装等。

通过这个实验,我们对操作系统的基本安装和配置有了更深入的了解。

实验二:进程管理进程是操作系统中最基本的执行单位,也是操作系统资源管理的核心。

在这个实验中,我们学习了进程的创建、调度和终止等操作。

通过编写简单的程序,我们可以观察到进程的创建和调度过程,了解进程的状态转换和资源分配。

同时,我们还学习了进程间通信的方式,如共享内存和消息传递等。

通过这个实验,我们对进程管理有了更深入的理解。

实验三:内存管理内存管理是操作系统中重要的一部分,它负责管理和分配计算机的内存资源。

在这个实验中,我们学习了内存的分配和回收算法,如连续分配和非连续分配等。

通过编写程序,我们可以观察到内存的分配和回收过程,了解内存的管理策略和算法。

同时,我们还学习了虚拟内存的概念和实现原理,通过页面置换算法实现了虚拟内存的管理。

通过这个实验,我们对内存管理有了更深入的认识。

实验四:文件系统文件系统是操作系统中用于管理和存储文件的一种机制。

在这个实验中,我们学习了文件系统的基本操作和管理技巧。

通过创建文件、目录和链接等操作,我们可以更好地理解文件系统的结构和组织方式。

同时,我们还学习了文件的读写和权限管理等操作,通过编写程序实现了对文件的操作。

通过这个实验,我们对文件系统有了更深入的了解。

实验五:设备管理设备管理是操作系统中负责管理和控制计算机设备的一种机制。

西工大 操作系统实验报告

西工大 操作系统实验报告

西工大操作系统实验报告西工大操作系统实验报告一、引言操作系统是计算机系统中最重要的软件之一,它负责管理计算机硬件和软件资源,为用户提供一个友好、高效的计算环境。

本次实验旨在通过实践操作系统的基本功能和原理,加深对操作系统的理解和掌握。

二、实验目的1. 理解操作系统的基本概念和作用;2. 学习操作系统的安装和配置;3. 掌握操作系统的文件管理和进程管理;4. 实践操作系统的调度算法和内存管理;5. 深入理解操作系统的并发控制和死锁处理。

三、实验环境本次实验使用的操作系统是Linux,具体版本为Ubuntu 20.04 LTS。

实验所需的软件和工具包括GCC编译器、Make工具、Vi编辑器等。

四、实验内容1. 操作系统的安装和配置首先,我们需要下载Ubuntu 20.04 LTS的镜像文件,并通过虚拟机软件创建一个虚拟机。

然后,按照提示进行操作系统的安装和配置,包括选择安装语言、分配磁盘空间、设置用户名和密码等。

安装完成后,我们可以登录系统,并进行一些基本设置,如修改主题、安装常用软件等。

2. 文件管理和进程管理操作系统的文件管理是指对计算机中的文件进行组织、存储和访问的过程。

我们可以使用命令行或图形界面来管理文件,包括创建文件、复制文件、删除文件等。

同时,操作系统还提供了进程管理的功能,可以管理计算机中运行的各个进程。

我们可以使用命令行或系统监视器来查看和管理进程,包括启动进程、终止进程、调整进程优先级等。

3. 调度算法和内存管理操作系统的调度算法是指决定哪个进程在何时执行的算法。

常见的调度算法包括先来先服务、短作业优先、轮转调度等。

我们可以通过修改系统的调度策略来改变进程的执行顺序。

另外,操作系统还负责管理计算机的内存资源,包括内存分配、内存回收等。

我们可以使用命令行或系统监视器来查看和管理内存,包括查看内存使用情况、释放内存空间等。

4. 并发控制和死锁处理操作系统需要保证多个进程之间的并发执行,同时又要避免出现竞争条件和死锁等问题。

OS实验报告2

OS实验报告2

实验2 Linux进程的软中断通信与管道通信学生姓名张锦涛学号20091602310002 专业班级2011级计本1班实验地点信息学院222 实验日期2011-04-26 指导教师张春元、卢春燕实验环境Ubuntu Linux + gcc 实验学时2学时1.实验目的(1)加深对进程概念的理解,明确进程和程序的区别;(2)进一步认识并发执行的实质;(3)分析进程争用资源的现象,学习解决进程互斥的方法;(4)了解Linux系统中进程通信的基本原理。

2.实验内容(1)编制一段程序并适当加以注释,实现软中断通信:在系统中调用signal()让父进程捕捉键盘上来的Del键中断信号实现父进程中断;使用系统调用fork()函数创建两个子进程,当父进程接受到这两个软中断的其中某一个后,父进程用系统调用kill()函数向两个子进程分别发送整数值为17和17软中断信号,子进程获得对应信号后,分别输出下列信息后终止:Child process 1 is killed by parent !Child process 2 is killed by parent !父进程调用wait()函数等待两个子进程终止后,输出以下信息后终止:Parent process is killed!!多运行几次编写的程序,简略分析出现不同结果的原因。

(2)编制一段程序并适当加以注释,实现进程的管道通信:使用系统调用pipe()建立一条管道线,两个子进程分别向管道各写一句话:Child process 1 is sending a message!Child process 2 is sending a message!而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。

要求:父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。

3.实验过程及分析(1)实验内容1源代码及运行分析:(2)实验内容2源代码及运行分析:4.实验总结(写出实验中的心得体会)。

计算机操作系统实验课实验报告

计算机操作系统实验课实验报告

计算机操作系统实验课实验报告一、实验目的本次计算机操作系统实验课的主要目的是通过实际操作和观察,深入理解计算机操作系统的基本原理和功能,提高对操作系统的实际运用能力和问题解决能力。

二、实验环境本次实验使用的计算机配置为:处理器_____,内存_____,操作系统为_____。

实验所使用的软件工具包括_____。

三、实验内容及步骤(一)进程管理实验1、编写程序创建多个进程,并观察进程的执行顺序和资源分配情况。

首先,使用编程语言(如 C 或 Java)编写代码,创建多个进程。

然后,通过操作系统提供的工具(如任务管理器)观察进程的创建、执行和结束过程。

记录不同进程的执行时间、CPU 使用率和内存占用情况。

2、实现进程间的通信机制,如管道、消息队列等。

分别编写使用管道和消息队列进行进程间通信的程序。

在程序中发送和接收数据,并观察通信的效果和数据的完整性。

(二)内存管理实验1、模拟内存分配算法,如首次适应算法、最佳适应算法和最坏适应算法。

编写程序实现上述三种内存分配算法。

输入不同的内存请求序列,观察每种算法下内存的分配情况和碎片产生情况。

2、研究虚拟内存的工作原理,并进行相关实验。

通过操作系统的设置,调整虚拟内存的大小。

运行大型程序,观察虚拟内存的使用情况和系统性能的变化。

(三)文件系统实验1、实现文件的创建、读写和删除操作。

使用编程语言创建文件,并向文件中写入数据。

读取文件中的内容,并进行验证。

删除文件,观察文件系统的变化。

2、研究文件系统的目录结构和文件权限管理。

观察文件系统的目录层次结构,了解目录的组织方式。

设置文件的权限,如只读、读写、执行等,观察不同权限对文件操作的影响。

四、实验结果与分析(一)进程管理实验结果与分析1、在创建多个进程的实验中,发现进程的执行顺序并非完全按照创建的顺序,而是由操作系统的调度算法决定。

某些进程可能会因为等待资源而暂时被挂起,而其他进程则会得到执行机会。

2、通过进程间通信实验,发现管道通信方式简单直接,但只能用于具有亲缘关系的进程之间;消息队列则更加灵活,可以在不同的进程之间传递消息,但需要更多的编程和管理工作。

西北工业大学-操作系统实验报告-实验二

西北工业大学-操作系统实验报告-实验二

实验二FreeBSD的应用软件安装一、实验目的学习如何使用FreeBSD安装应用软件。

二、实验内容与要求1、查阅资料,了解FreeBSD 安装软件的主要方式,每种方式的具体步骤、操作指南;2、学习使用FreeBSD安装方法的一种进行安装简单的SSH;3、详细记录探索学习的内容和实验的整个过程,包括资料的查询、资料的来源(资料名称、网址等)、所做的各种尝试、以及最终的结果(包含截屏);三、实验过程1、FreeBSD 安装软件的主要方式(1).package用 package 安装,只要抓取该程序 package 档案,简单的透过 --> 安装pkg_add package_name --> 移除 pkg_delete package_name就可以完成安装 / 移除。

注意:文件名称 .tgz 结尾的是 package 文件名称 .tar.gz 结尾的是 source 注 : 目前已经安装的 package 数据库放在 /var/db/pkg/ 这个数据夹之中。

通常在比较大型的套件(需要编译很久)或是老是无法编译成功以及想先快速了解未使用过的套件是长成什么样子时,我们会采用这种方式来安装套件。

(2)port如果你要使用 ports 安装软件,你必须先确认 /usr/ports 这个目录是否有安装。

如果没有的话,使用 /stand/sysinstall 来安装 ports 的目录:1. 以 root 执行 /stand/sysinstall2. 选择 Configure 后按 Enter3. 选择 Distributions 后按 Enter4. 选择 ports 后按空格键5. 选择 Exit 后按 Enter6. 选择你要从 CDROM 或 FTP 安装等7. 跟着选单照做,最后离开 sysinstall或者我们也可以到 /ports/ 去手动抓回 port.tar.gz 这个档案,将它放在 /usr/ 下。

操作系统实验报告2doc

操作系统实验报告2doc

操作系统实验报告2篇一:操作系统实验二实验报告操作系统实验报告——实验二:线程和管道通信实验一、实验目的通过 Linux 系统中线程和管道通信机制的实验,加深对于线程控制和管道通信概念的理解,观察和体验并发进(线)程间的通信和协作的效果 ,练习利用无名管道进行进(线)程间通信的编程和调试技术。

二、实验说明1) 与线程创建、执行有关的系统调用说明线程是在共享内存中并发执行的多道执行路径,它们共享一个进程的资源,如进程程序段、文件描述符和信号等,但有各自的执行路径和堆栈。

线程的创建无需像进程那样重新申请系统资源,线程在上下文切换时也无需像进程那样更换内存映像。

多线程的并发执行即避免了多进程并发的上下文切换的开销又可以提高并发处理的效率。

pthread 库中最基本的调用。

1.pthread_create 系统调用语法:#includeInt pthread_create(pthread_t *thread,pthread_attr_t *attr,void *(*start_routine)(void *) Void *arg);pthread_create 函数创建一个新的线程。

pthread_create 在 thread 中保存新线程的标识符。

Attr 决定了线程应用那种线程属性。

使用默认可给定参数 NULL; (*start_routine) 是一个指向新线程中要执行的函数的指针 arg 是新线程函数携带的参数。

Pthread_create 执行成功会返回0并在 thread 中保存线程标识符。

执行失败则返回一个非0的出错代码2.pthread_exit 系统调用语法:#includevoid pthread_exit(void *retval);pthread_exit 函数使用函数pthread_cleanup_push 调用任何用于该线程的清除处理函数,然后中止当前进程的执行,返回 retval。

最新操作系统实验报告实验二

最新操作系统实验报告实验二

最新操作系统实验报告实验二实验目的:1. 熟悉最新操作系统的架构和特性。

2. 掌握操作系统的基本操作和配置方法。

3. 分析操作系统的性能和稳定性。

实验环境:- 硬件环境:Intel Core i7处理器,16GB RAM,256GB SSD。

- 软件环境:最新操作系统版本X.Y.Z,图形界面和命令行界面。

实验步骤:1. 安装最新操作系统X.Y.Z,记录安装过程中的关键步骤和遇到的问题。

2. 配置系统环境,包括网络设置、显示设置、用户账户管理等。

3. 测试文件系统的性能,包括文件的创建、复制、删除和搜索操作。

4. 测试多任务处理能力,通过同时运行多个应用程序来观察系统响应时间和资源分配情况。

5. 检验系统的安全性,包括用户权限管理、防火墙设置和病毒防护功能。

6. 评估系统的稳定性,进行长时间运行测试,记录是否有崩溃或异常行为发生。

7. 对系统进行基准测试,使用专业工具如SPEC CPU测试套件来评估系统性能。

实验结果:1. 安装过程中,系统顺利识别硬件并完成驱动安装,未遇到兼容性问题。

2. 系统配置简便,图形用户界面直观易用,网络配置通过向导快速完成。

3. 文件系统测试显示,读写速度达到预期标准,搜索操作响应迅速。

4. 多任务处理测试中,系统在开启多个资源密集型应用时仍保持流畅,未出现明显延迟。

5. 安全性测试表明,用户权限分级明确,防火墙和病毒防护均能有效工作。

6. 稳定性测试中,系统连续运行72小时无故障,表现出良好的稳定性。

7. 基准测试结果显示,系统性能较前一版本有显著提升,特别是在多线程处理方面。

实验结论:最新操作系统X.Y.Z在本次实验中表现出了良好的性能和稳定性。

系统的用户界面友好,配置和管理方便。

文件系统和多任务处理能力均达到预期目标,安全性和稳定性也符合最新的操作系统标准。

推荐对性能和稳定性有较高要求的用户进行升级。

OS上机实验报告(2)

OS上机实验报告(2)

课程设计(上机实验)报告20XX 年月日课程设计(上机实验)报告填写说明1.本报告作为指导教师对学生课程设计(上机实验)评分的依据材料之一。

此报告应在指导教师指导下,由学生在课程设计(上机实验)结束时完成,以班为单位收齐后按时交给指导教师审阅;2.本报告内容必须用黑墨水笔工整书写或者按信息学院统一设计的电子文档标准格式(可从信息学院网页上下载)打印(小4 号宋体, 1.5 倍行距),禁止打印在其它纸上后剪贴;3.本报告中的“设计说明书”应按论文的格式成文,并直接书写(或者打印)在本报告“设计说明书”栏目内。

其内容可以结合设计题目的内容和要求,根据自己在本课程设计(上机实验)阶段所完成的工作,阐明自己所采取的设计思想和方法 (硬件的设计及其电原理图分析介绍,和/或者软件的算法和数据结构及其主要模块介绍、程序在测试用例下的测试运行结果等)、完成本课程设计的心得体味、设计中的不足及改进设计的设想或者建议等。

说明书的篇幅应不少于2000 字。

4.对硬件类课程设计,应绘制或者打印硬件设计图纸或者实验原理图,作为设计报告的附件。

5.软件类课程设计(上机实验)的软件文档(含软件清单和程序运行的有关结果) 可以单独打印成册或者上传到指导教师指定计算机,作为课程设计报告的附件。

课程设计 (上机实验) 报告的附件是指导教师对学生课程设计(上机实验)评分的另一个依据。

文件系统的摹拟设计理解操作系统文件系统的某些工作原理,学习文件操作命令和目录操作命令的设计方法。

通过实验,使学生加深对操作系统文件系统某些问题的理解,归纳学习方法和思考方法,做到理论联系实际。

培养学生分析问题、解决问题的能力,提高学生软件设计能力和逻辑思维能力。

内容和要求:设计实现一个简单的文件系统,包括目录文件、普通文件,以及一些文件操作命令和目录操作命令(例如可以摹仿DOS 的有关命令)。

具体要求如下列 2.2 和 2.3。

程序初始化时构造如图 1 所示的目录结构。

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

评语:
成绩: 指导教师:
实验报告二
实验名称:构造进程家族树
日期:2013-5-16
理解进程的独立空间
一、实验目的:
1. 通过创建若干个子进程,构造进程家族树,分析进程家族树的结构关系;学
习相关系统调用(例如,getpid()和getppid()等)的使用方法。

2. 理解进程是操作系统独立分配资源的单位,进程拥有自己相对独立的程序空
间。

二、实验内容:
1. 进程的创建:编制一段程序,使用系统调用fork()创建三个子进程,在各个子
进程中再使用系统调用fork()进一步创建子进程,如此重复,构造一棵进程家
族树。

分别使用系统调用getpid()和getppid()获取当前进程和父进程的
进程标识号并输出。

2. (1)编写一个程序,在其main()函数中定义一个变量shared,对其进行循
环加/减操作,并输出每次操作后的结果;
(2)使用系统调用fork()创建子进程,观察该变量的变化;
(3)修改程序把shared 变量定义到main()函数之外,重复第(2)步操作,观察该变量的变化。

三、项目要求及分析:
1.学习进程构造的相关知识,学习获取进程相关信息的系统调用函数。

利用系统调用getpid()和getppid()所获得的进程标识号信息,验证是否进程间关系是否满足要求的进程家族树。

2.了解进程创建和构造的相关知识,了解C语言程序编写的相关知识。

观察进程执行结果,根据进程间的执行关系思考原因,并和线程进行比较。

四、具体实现:
4.1 流程图
1.进程家族树
Pid_1=fork()
Pid_2=fork()
Pid_1<0?
error
Pid_1==0?
输出pid 和ppid
Pid_2<0?
ERROR
Y N
Y Y Pid_2==0?
Pid_2_1=fork()
Pid_2_1<0?
ERROR
Y
Y Pid_2_1==0?
输出pid 和ppid
Pid_2_2=fork()
N
Y
pid1>0?Pid_2_1>0?
Pid_2_2<0?
ERROR
Pid_2_2==0?
输出pid 和ppid
N
Y
Pid_2>0?
Pid_3=fork()
Pid_3<0?
ERROR Pid_3==0?
输出pid 和ppid
N
N Y
Y Y Y
N
N Y
N Y
2.
pid=fork()
ERROR
pid<0pid==0pid>0N
N
Y Y
Y
shared=1
输出shared
操作
输出shared
操作
4.2 添加函数的代码
1.创建进程,实现如下图的进程家族树
#include<unistd.h> #include<sys/types.h>
int main()
int pid_1, pid_2, pid_3, pid_2_1, pid_2_2;
pid_1=fork();
if(pid1<0)
printf(“ERROR\n”);
else if(pid_1==0)
printf(“My father Id is %d, My Id is %d\n”,getppid(), getpid());
else if(pid_1>0)
{
pid_2=fork();
if(pid_2<0)
printf(“ERROR\n”);
else if(pid_2==0)
{
printf(“My father Id is %d, My Id is %d\n”,getppid(), getpid());
pid_2_1=fork();
if(pid_2_1<0)
printf(“ERROR\n”);
else if(pid_2_1==0)
{
printf(“My father Id is %d, My Id is %d\n”,getppid(), getpid());
}
else if(pid_2_1>0)
{
pid_2_2=fork();
if(pid_2_2<0)
printf(“ERROR\n”);
else if(pid_2_2==0)
{
printf(“My father Id is %d, My Id is %d\n”,getppid(), getpi d());
}
}
}
else if(pid_2>0)
{
pid_3=fork();
if(pid_3<0)
printf(“ERROR\n”);
else if(pid_3==0)
{
printf(“My father Id is %d, My Id is %d\n”,getppid(), getpid());
}
}
}
return 0;
2. 无进程时:
#include<unistd.h>
#include<sys/types.h>
int main()
{
int shared=1;
shared++;
printf(“%d\n”, shared);
shared--;
printf(“%d\n”, shared);
shared++;
printf(“%d\n”, shared);
shared--;
printf(“%d\n”, shared);
}
4.3 修改原有函数部分代码
在2的基础上创建子进程,并尝试把shared变量放到主函数之外:#include<unistd.h>
#include<sys/types.h>
int shared=1;
int main()
{
int pid;
pid=fork();
if(pid<0)
printf(“ERROR\n”);
if(pid>0)
{
shared++;
printf(“%d\n”, shared);
shared--;
printf(“%d\n”, shared);
shared++;
printf(“%d\n”, shared);
shared--;
printf(“%d\n”, shared);
}
if(pid==0)
{
shared++;
printf(“%d\n”, shared);
shared--;
printf(“%d\n”, shared);
shared++;
printf(“%d\n”, shared);
shared--;
printf(“%d\n”, shared);
}
}
五、调试运行结果:
1.创建进程家族树,根据程序运行输出结果,观察各进程pid和ppid的关系,可看出与要求的进程家族树相符。

运行结果如图:
27321
27325 2732426326
2732227323
2.未添加进程创建语句时的程序运行结果如下:
添加进程创建语句后,程序运行结果如下,子进程和父进程都执行了操作,且彼此之间对于同一个变量shared的自加操作互不影响。

当把shared放到主函数之外的运行结果,和内部时相比,并未发生变化。

六、所遇问题及解决方法:
实验过程中由于一开始对fork()语句的不了解,或者说是认识的模糊,采用了循环语句编写代码,始终不能完成进程树的创建,在和同学交流之后,在助教的指导下对fork()语句有了清楚地认识,采用正常的语句编写规范完成了实验要求。

七、实验总结:
1. 对于fork()语句的使用还是不够熟练和清楚,在使用的过程中过于心急,对
程序本真的内在含义理解不清楚,还要在课后认真的学习和弥补不足。

2. 实验过程中,交流很重要,不过还是要加强自己的学习能力,提高对程序的
理解能力和使用技巧。

相关文档
最新文档