| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> 操作系统课程设计 -> 正文阅读 |
|
[系统运维]操作系统课程设计 |
关于完整代码&更详细内容&实验一环境配置 请访问github仓库地址:GitHub - zzering/OS-course-design: 操作系统课设:系统调用,磁盘调度算法,文件调用,进程管理,分页置换算法,进程通信 实验一:为Linux系统增加系统调用1.1程序功能及设计思路1.1.1程序功能通过修改Linux 0.11系统文件(使用Bochs运行), 实现增加一个简单的系统调用 1.1.2设计思路在用户层面编写程序nameout.c,通过syscall这个宏开启调用系统函数的窗口,调用sys_nameout系统函数。 详细步骤: 文件路径:/linux-0.11/include/unistd.h 修改系统调用总数 为新增的系统调用添加系统调用名并维护系统调用表 ?为新增的系统调用编写代码实现,创建一个文件? ?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; } 采用挂载方式实现宿主机与虚拟机操作系统的文件共享,在? 编译linux内核 终端执行 make命令 ?Make成功 运行Bochs虚拟机 为linux-0.11新增调用号 (若在虚拟机中修改)
? 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” 父进程用系统调用signal()来捕捉中断信号,用kill()向两个子进程发出信号,子进程输出如下信息后终止: Child Process 1 is killed by Parent! Child Process 2 is killed by Parent! 父进程等待两个子进程终止后,释放管道并输出Parent Process is Killed! 4.1.2设计思路定义两个进程 子进程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创建共享存储区, 然后获取其首地址, 使用while (*addr == -1)阻塞自身, 用于进程同步 client端 client打开共享存储区, 然后获取其首地址, 使用while (*addr != -1)阻塞自身 6.2程序运行情况及截图 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/30 1:44:27- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |