操作系统课程设计

2023-11-18

关于完整代码&更详细内容&实验一环境配置 请访问github仓库地址:GitHub - zzering/OS-course-design: 操作系统课设:系统调用,磁盘调度算法,文件调用,进程管理,分页置换算法,进程通信

实验一:为Linux系统增加系统调用

1.1程序功能及设计思路

1.1.1程序功能

通过修改Linux 0.11系统文件(使用Bochs运行), 实现增加一个简单的系统调用
此处是调用nameout.c输出”Hello, I’m lwh”

1.1.2设计思路

在用户层面编写程序nameout.c,通过syscall这个宏开启调用系统函数的窗口,调用sys_nameout系统函数。
编写函数sys_nameout,以name.c的文件格式保存在了linux0.11系统kernel中;
sys_nameout调用了printk()完成打印输出。
修改Makefile文件让我们添加的 kernel/who.c 可以和其它 Linux 代码编译链接到一起

详细步骤:
添加iamwhoami系统调用编号的宏定义(_NR_xxxxxx)

文件路径:/linux-0.11/include/unistd.h

修改系统调用总数
文件路径:/linux-0.11/kernel/system_call.s

为新增的系统调用添加系统调用名并维护系统调用表
文件路径:/linux-0.11/include/linux/sys.h

 为新增的系统调用编写代码实现,创建一个文件 name.c
文件路径: /linux-0.11/kernel

 name.c中写入printk(”Hello, I’m lwh”)

修改 Makefile

要想让我们添加的 kernel/who.c 可以和其它 Linux 代码编译链接到一起,必须要修改 Makefile 文件

文件路径: / linux-0.11/kernel/Makefile

编写测试程序

到此为止,内核中需要修改的部分已经完成,接下来需要编写测试程序来验证新增的系统调用是否已经被编译到linux-0.11内核可供调用

文件路径:/oslab/namein.c /oslab/nameout.c

 /* nameout.c */

#define __LIBRARY__

#include <unistd.h>

#include <errno.h>

#include <asm/segment.h>

#include <linux/kernel.h>

#include <stdio.h>

_syscall2(int, nameout,char *,name,unsigned int,size);

int main(int argc, char *argv[])

{

    char username[64] = {0};

    /*调用系统调用nameout()*/

    nameout(username, 24);

    printf("%s\n", username);

    return 0;

}

采用挂载方式实现宿主机与虚拟机操作系统的文件共享,在 oslab 目录下执行以下命令挂载hdc目录到虚拟机操作系统上

编译linux内核
文件路径: /oslab/linux

终端执行 make命令

 Make成功

运行Bochs虚拟机
文件路径: /oslab/
终端执行 run命令

为linux-0.11新增调用号
文件路径: 虚拟机中/usr/include/unistd.h(也可以挂载后在图形界面中修改)

(若在虚拟机中修改)



(若挂载后在主机的图形界面中修改)

 

gcc运行 成功输出案例文字

1.2程序运行情况及截图

实验二:磁盘调度

2.1程序功能及设计思路

2.1.1程序功能

使用FIFO(先来先服务)、SSTF(最短寻道优先)以及SCAN(电梯调度算法)进行磁盘调度

显示调度顺序, 计算出平均移动磁道数

2.1.2设计思路

定义两个全局变量

int a[MAX];//存放要用到的磁道号

int start;//记录开始的磁道

主函数中设计一个循环, 生成界面, 并使其能够调用3个磁盘调用算法

2.2算法设计

2.2.1求平均值函数

将每次寻道的距离数组length[]传入函数, 将其累加求平均值

2.2.2先来先服务算法

定义visit[]数组, 来记录请求是否被处理, 若处理过, 则查看下一个请求 

求出每次寻道的距离, 将其放入length[]中

2.2.3最短寻道时间优先算法

定义flag记录当前最短路径下标 

用for循环找没有访问过的中最近的 

每找到一个将其放入length[]中, 并设为已访问

2.2.4扫描算法

调用sort函数将所有请求按从小到大排序 

通过for循环找到离当前磁头最近的请求磁道, 随后往递增方向访问, 全部访问完成, 再往递减方向访问 

每次访问完更新磁头位置

2.3程序运行情况及截图

 

 

 

实验三: Linux系统文件调用接口

3.1程序功能及设计思路

3.1.1程序功能

使用文件系统调用编写一个文件工具 filetools,使其具有以下功能:

创建新文件, 写文件, 读文件, 修改文件权限, 查看当前文件权限, 退出

3.1.2设计思路

模拟类似shell的效果即通过touch a.cpp, echo “hello” >> a.cpp这样的方式实现文件管理
实现各个文件操作的函数
编写一个函数对输入的操作进行字符串处理和判断, 然后调用相应的函数

 

3.2算法设计

3.2.1创建新文件函数

umask(0000); //建立新文件时的权限遮罩

通过open(filename, O_RDWR | O_CREAT, 0666)函数创建文件

得到的文件权限为0666-0000

fd<0, 提示创建失败

3.2.2写文件函数

通过open(filename, O_WRONLY);打开指定文件, 权限是只写

write(fd, buffer, strlen(buffer));将缓存区的内容写入
 

3.2.3读文件函数

open(filename, O_RDONLY); 打开指定文件, 权限是只读

lseek(fd, 0, SEEK_SET); lseek函数定位一个已经打开的文件, 2 3参数将读写位置移到文件开头
创建缓存区

read(fd, buffer, 1 << 15);读取内容到缓存区

打印缓冲区内容

3.2.4修改文件权限函数

打开指定文件

十进制转八进制

int mode_u = mode / 100;                                     // user

int mode_g = mode / 10 % 10;                              // group

int mode_o = mode % 10;                                            // others

mode = (mode_u * 8 * 8) + (mode_g * 8) + mode_o;

chmod(filename, mode);修改权限

3.2.5查看文件权限
打开指定文件

char *pargv[4] = {"ls", "-l", NULL, NULL};

需要将文件名传到*pargv[2]

pargv[2] = (char *)malloc(50);

strcpy(pargv[2], filename);

查看指定文件的权限

execv("/bin/ls", pargv);

3.2.6输入处理函数

通过sstream, 处理输入的字符

touch cat echo chmod ll 的前两个字母通过s.find来查找字符中是否存在对应的关键字, 若存在, 就调用对应函数

2.3程序运行情况及截图

交互界面

新建文件

写入文件

查看文件

改变文件权限

查看文件权限

实验四: 进程管理

4.1程序功能及设计思路

4.1.1程序功能

父进程使用pipe()建立一个管道,然后调用fork()创建子进程1和子进程2

子进程1每隔1秒通过管道向子进程2发送数据“I send message x times”
子进程2从管道读出信息,并显示在屏幕上

父进程用系统调用signal()来捕捉中断信号,用kill()向两个子进程发出信号,子进程输出如下信息后终止: Child Process 1 is killed by Parent! Child Process 2 is killed by Parent!

父进程等待两个子进程终止后,释放管道并输出Parent Process is Killed!

4.1.2设计思路

定义两个进程
定义两个缓存区msg和buffer

子进程1中输出字符串到msg中,调用write函数将其写入到fd[1]中

子进程2调用read函数将fd[0]中的数据读入到buffer中, 然后将其输出

两进程中都使用signal(SIGINT, SIG_IGN);屏蔽系统定义的结束, 通过signal(SIGUSR1, userDefinedSignal);来调用自定义的信号对应的结束的函数

4.2程序运行情况及截图

实验五: 请求分页系统中的置换算法

5.1程序功能及设计思路

5.1.1程序功能

产生320条指令序列

将指令序列变换成页地址流

分别计算先进先出(FIFO)页面置换算法,最近最久未使用(LRU)页面置换算法,最佳(Optimal)页面置换算法在不同内存页块下的命中率

5.1.2设计思路

实现三种算法 

设计一个取指令函数,得到320个随机的指令序列 

主函数中设计一个循环, 依次输出计算出的值

5.2算法设计

5.2.1 FIFO算法

用链表模拟队列。初始化之后,每次取得下一个指令,检查队列中存在对应的页号,如果存在命中次数加1,否则删除队列中第一个页号,插入当前页号

5.2.2 LRU算法

当需要淘汰一个页面时,总是选择在最近一段时间内最久不用的页面予以淘汰。定义一个结构体,保存指令所在的页号和在队列中没有被访问的次数。如果需要淘汰,每次淘汰没有被访问次数最多的页号

5.2.3 OPT算法

从主存中移出永远不再需要的页面;如无这样的页面存在,则选择最长时间不需要访问的页面。于所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。每次淘汰时,评估每一个页号将来的位置,淘汰最长时间不需要访问的页面

5.2.4 取指令函数

使用srand()函数 设定时间种子。使用随机函数rand() % M得到0~M - 1的随机数(M < MAX_INT),当指令到达320时,停止生成指令。最后除以1024得到所在的页号。

主函数中设计一个循环, 依次输出计算出的值

5.3程序运行情况及截图

实验六: 进程通信

6.1程序功能及设计思路

6.1.1程序功能

使用管道来实现父子进程之间的进程通信 

使用消息缓冲队列来实现 client 进程和 server 进程之间的通信 

使用共享存储区来实现两个进程之间的进程通信

6.1.2设计思路

1.通过管道通信

定义两个缓存区msg和buffer 

子进程1中输出字符串到msg中,调用write函数将其写入到fd[1]中 

父进程调用read函数将fd[0]中的数据读入到buffer中, 然后将其输出 

2.通过消息缓冲队列通信

server端:

server 进程先建立一个关键字为 SVKEY(如 75)的消息队列,然后等待接收类型为 REQ(例如 1)的消息; 

在收到请求消息后,它便显示字符串“serving for client”和接收到的 client 进程的进程标识数,表示正在为 client 进程服务; 

然后再向 client 进程发送应答消息,该消息的类型是 client 进程的进程标识数,而正文则是 server 进程自己的标识ID。 

client端:

client 进程则向消息队列发送类型为 REQ 的消息(消息的正文为自己的进程标识 ID) 以取得 sever 进程的服务,并等待 server 进程发来的应答;  

然后显示字符串“receive reply from”和接收到的 server 进程的标识 ID 

3.通过共享缓存区通信量
server端

server创建共享存储区, 然后获取其首地址, 使用while (*addr == -1)阻塞自身, 用于进程同步

client

client打开共享存储区, 然后获取其首地址, 使用while (*addr != -1)阻塞自身

6.2程序运行情况及截图

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

操作系统课程设计 的相关文章

  • diff 文件仅比较每行的前 n 个字符

    我有2个文件 我们将它们称为 md5s1 txt 和 md5s2 txt 两者都包含a的输出 find type f print0 xargs 0 md5sum sort gt md5s txt 不同目录下的命令 许多文件被重命名 但内容保
  • 在 Linux 上的 Python 中使用受密码保护的 Excel 工作表

    问题很简单 我每周都会收到一堆受密码保护的 Excel 文件 我必须解析它们并使用 Python 将某些部分写入新文件 我得到了文件的密码 当在 Windows 上完成此操作时 处理起来很简单 我只需导入 win32com 并使用 clie
  • 如何制作和应用SVN补丁?

    我想制作一个SVN类型的补丁文件httpd conf这样我就可以轻松地将其应用到其他主机上 If I do cd root diff Naur etc httpd conf httpd conf original etc httpd con
  • xsel -o 对于 OS X 等效项

    是否有一个等效的解决方案可以在 OS X 中抓取选定的文本 就像适用于 Linux 的 xsel o 一样 只需要当前的选择 这样我就可以在 shell 脚本中使用文本 干杯 埃里克 你也许可以安装xsel在 MacOS 上 更新 根据 A
  • 如何修复“iptables:没有该名称的链/目标/匹配”?

    我在我的 Linux 嵌入式系统上构建并安装了 iptables 如果我列出所有规则 则一切正常 iptables list Chain INPUT policy ACCEPT target prot opt source destinat
  • 如何检测并找出程序是否陷入死锁?

    这是一道面试题 如何检测并确定程序是否陷入死锁 是否有一些工具可用于在 Linux Unix 系统上执行此操作 我的想法 如果程序没有任何进展并且其状态为运行 则为死锁 但是 其他原因也可能导致此问题 开源工具有valgrind halgr
  • 从 csv 文件中删除特定列,保持输出上的相同结构[重复]

    这个问题在这里已经有答案了 我想删除第 3 列并在输出文件中保留相同的结构 输入文件 12 10 10 10 10 1 12 23 1 45 6 7 11 2 33 45 1 2 1 2 34 5 6 I tried awk F 3 fil
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • Jenkins中找不到环境变量

    我想在詹金斯中设置很多变量 我试过把它们放进去 bashrc bash profile and profile of the jenkins用户 但 Jenkins 在构建发生时找不到它们 唯一有效的方法是将所有环境变量放入Jenkinsf
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 为什么内核需要虚拟寻址?

    在Linux中 每个进程都有其虚拟地址空间 例如 32位系统为4GB 其中3GB为进程保留 1GB为内核保留 这种虚拟寻址机制有助于隔离每个进程的地址空间 对于流程来说这是可以理解的 因为有很多流程 但既然我们只有 1 个内核 那么为什么我
  • 无法从 jenkins 作为后台进程运行 nohup 命令

    更新 根据下面的讨论 我编辑了我的答案以获得更准确的描述 我正在尝试从詹金斯运行 nohup 命令 完整的命令是 nohup java jar home jar server process 0 35 jar prod gt gt var
  • 从 Python 调用 PARI/GP

    我想打电话PARI GP http pari math u bordeaux fr dochtml gpman html仅从Python计算函数nextprime n 对于不同的n是我定义的 不幸的是我无法得到帕里蟒蛇 http code
  • chown:不允许操作

    我有问题 我需要通过 php 脚本为系统中的不同用户设置文件所有者权限 所以我通过以下命令执行此操作 其中 1002 是系统的用户 ID file put contents filename content system chown 100
  • 在哪里可以找到并安装 pygame 的依赖项?

    我对 Linux 比较陌生 正在尝试安装 python 的 pygame 开发环境 当我运行 setup py 时 它说我需要安装以下依赖项 我找到并安装了其中之一 SDL 然而 其他人则更加难以捉摸 Hunting dependencie
  • 使用 sed 更新 xml 属性(Windows + cygwin 和 Linux)?

    我需要使用 sed 命令对 xml 文件进行更新 但我在这方面遇到了麻烦 它需要在 Windows 使用 cygwin 和 Linux 上运行 XML 具有以下元素
  • Linux 中的动态环境变量?

    Linux 中是否可以通过某种方式拥有动态环境变量 我有一个网络服务器 网站遵循以下布局 site qa production 我想要一个环境变量 例如 APPLICATION ENV 当我在 qa 目录中时设置为 qa 当我在生产目录中时
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • arm64和armhf有什么区别?

    Raspberry Pi Type 3 具有 64 位 CPU 但其架构不是arm64 but armhf 有什么区别arm64 and armhf armhf代表 arm hard float 是给定的名称Debian 端口 https
  • 如何在 Linux shell 中将十六进制转换为 ASCII 字符?

    假设我有一个字符串5a 这是 ASCII 字母的十六进制表示Z 我需要找到一个 Linux shell 命令 它将接受一个十六进制字符串并输出该十六进制字符串代表的 ASCII 字符 所以如果我这样做 echo 5a command im

随机推荐

  • Python基于控制台的学生管理系统

    encoding utf 8 定义一个函数 显示可以使用的功能列表给用户 def showInfo print 30 print 学生管理系统 v1 0 print 1 添加学生的信息 print 2 删除学生的信息 print 3 修改学
  • MIPI信号的分析--结合示波器实际测试波形

    如果排查的思路对你有帮助 请记住 消雨匆匆 码字和排查很累 仅此而已 硬件不是抄电路 拿烙铁 懂点软件 细致分析 找问题和破案搜集线索是一样的 PS 硬件知识也可以性感 部分内容来自于此博客的大神总结 http www elecfans c
  • Java+GeoTools实现WKT数据根据EPSG编码进行坐标系转换

    场景 Java GeoTools 开源的Java GIS工具包 快速入门 实现读取shp文件并显示 Java GeoTools 开源的Java GIS工具包 快速入门 实现读取shp文件并显示 霸道流氓气质的博客 CSDN博客 在上面实现J
  • 数字人+ChatGPT强强联手能擦出什么火花?

    随着元宇宙概念的快速发展 以数字人 ChatGPT为形式的创作方式正在颠覆传统视频创作方式 并在市场上呈现快速增长的态势 根据新榜的报道 目前已经有多位大V使用虚拟数字人来协助完成短视频制作 并且值得一提的是 这些视频并没有因为采用数字人而
  • 定时器编码器AB相电机测速( 补充)

    TIM编码器AB相电机测速 定时器编码器AB相电机测速 1 四倍频 2 算法应用 3 stm32硬件连接 3 stm32环境配置端口配置 3 C语言实现编码器个数读取 3 C语言实现编码器个数转换为速度 定时器编码器AB相电机测速 1 四倍
  • vue3配置eslint 出现问题

    vue3配置eslint 出现问题 标题必须使用导入来加载 ES 模块 ESlint Error Must use import to load ES Module 加上这一行即可
  • Jmeter之ForEach控制器

    场景运用 ForEach控制器一般和用户自定义变量或者正则表达式提取器一起使用 其在用户自定义变量或者从正则表达式提取器的返回结果中读取一系列相关的变量 该控制器下的采样器或者控制器都会被执行一次或多次 每次读取不同的变量值 需求2 有一组
  • 学习java随堂练习-20220609

    学习Java的第八天 第1题 第2题 第3题 第4题 第5题 今天是学习Java的第八天 5道练习题 第1题 题目 1 循环输入近6年某高校的录取分数 求出平均分和最低分 运行结果 代码如下 循环输入近6年某高校的录取分数 求出平均分和最低
  • PHP操作Excel

    头 header Content Type application vnd ms excel header Content Disposition attachment filename sample xls header Pragma n
  • 时序预测

    时序预测 MATLAB实现DNN全连接神经网络时间序列预测 目录 时序预测 MATLAB实现DNN全连接神经网络时间序列预测 基本介绍 模型研究 程序设计 学习总结 参考资料 基本介绍 DNN的结构不固定 一般神经网络包括输入层 隐藏层和输
  • 传指针和传引用的区别以及指针和引用的区别

    一 引用 引用的定义 引用是给另外一个变量其别名 所以引用不会分配内存空间 引用是引入了对象的一个同义词 例如 Point pt1 10 10 Point pt2 pt1 上述的代码 定义了pt2为pt1的引用 通过这样的定义 pt2和pt
  • 让生产活动更高效,物料管理场景的RPA应用

    作为制造业 供应链领域常见环节 物料管理 Material Management 通常是对企业生产经营活动所需各种物料的采购 验收 供应 保管 发放 使用等一系列计划与控制活动的总称 物料管理科学与否 将会影响到组织各职能部门间的协调 生产
  • 文件的上传与下载

    一 文件上传 文件上传程序步骤 1 如何在web页面中添加上传输入项
  • python数据驱动测试设计_Python+unittest+DDT实现的数据驱动测试

    前言 数据驱动测试 避免编写重复代码 数据与测试脚本分离 通过使用数据驱动测试 来验证多组数据测试场景 通常来说 多用于单元测试和接口测试 ddt介绍 Data Driven Tests DDT 即数据驱动测试 可以实现不同数据运行同一个测
  • Gcov 详解 + 内核函数覆盖率测试方法详述及产生错误解决办法

    1 gcov是什么 Gcov is GCC Coverage 是一个测试代码覆盖率的工具 是一个命令行方式的控制台程序 伴随GCC发布 配合GCC共同实现对C C 文件的语句覆盖和分支覆盖测试 与程序概要分析工具 profiling too
  • 小白也能学会的爬虫教学(超详细,每一步都配图,不怕你学不会,图文并茂,看完直呼‘爽’)

    详细且简单的爬虫简单教学 小白看了之后直呼 爬虫就这 安装pycharm 一 新建一个工程 二 安装scrapy 三 创建Scrapy工程 四 如何使用scrapy 1 新建一个begin py文件 2 编辑begin py中的内容 3 修
  • hbase MapReduce程序样例入门

    hbase MapReduce程序样例入门 1 先看一个标准的hbase作为数据读取源和输出源的样例 Configuration conf HBaseConfiguration create Job job new Job conf job
  • 定时器:Quartz框架

    文章目录 简介 简单Demo cron 规则 参考 简介 Quartz是 OpenSymphony 开源组织在 Job scheduling 领域的开源项目 是由 java 开发的一个开源的任务日程管理系统 Quartz 是一个功能丰富的开
  • 如何下载安装VS2017下载 vs2017社区版

    如何下载安装VS2017下载 vs2017社区版 https blog csdn net zyhse article details 105362609 1 下载vs2017的引导程序 官方并没有为vs2017提供离线安装包 所以我们选择在
  • 操作系统课程设计

    关于完整代码 更详细内容 实验一环境配置 请访问github仓库地址 GitHub zzering OS course design 操作系统课设 系统调用 磁盘调度算法 文件调用 进程管理 分页置换算法 进程通信 实验一 为Linux系统