操作系统导论-课后作业-ch6

2024-01-17 03:44

本文主要是介绍操作系统导论-课后作业-ch6,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

补充:测量作业

1. 测试函数gettimeofday

代码如下:

#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>//return us
int time_diff(struct timeval* t1, struct timeval* t2) {return (t2->tv_sec - t1->tv_sec) * 1000000 + (t2->tv_usec - t1->tv_usec);
}int main() {int i;struct timeval curr, now;if (gettimeofday(&curr, NULL) == -1) {fprintf(stderr, "gettimeofday error\n");exit(1);}for (i = 0; i < 10; ++i) {if (gettimeofday(&now, NULL) != 0) {fprintf(stderr, "gettimeofday error\n");exit(1);}printf("time elaps %d us\n", time_diff(&curr, &now));}return 0;
}

执行结果如下:
在这里插入图片描述
最多精确到us,并且大致精确(并不完全精确),需要多迭代几次减少误差。

2. 测试系统调用时间

2.1 测试读取0字节耗时

本处以执行0字节的读取为例来测试此系统调用的时间:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>int time_diff(struct timeval* t1, struct timeval* t2) {return (t2->tv_sec - t1->tv_sec) * 1000000 + (t2->tv_usec - t1->tv_usec);
}int main() {int i;char buf[2];int fd = open("./tmp.txt", O_CREAT | O_APPEND | O_RDWR, S_IRWXU);struct timeval curr, now;if (gettimeofday(&curr, NULL) == -1) {fprintf(stderr, "gettimeofday error\n");exit(1);}for (i = 0; i < 100; ++i) {if (read(fd, buf, 0) != 0) {fprintf(stderr, "read error\n");exit(1);}}if (gettimeofday(&now, NULL) != 0) {fprintf(stderr, "gettimeofday error\n");exit(1);}printf("time elaps %d us\n", time_diff(&curr, &now));return 0;
}

执行结果如下:
在这里插入图片描述
执行了100次后的结果为19us,也就是每次执行调用耗时约0.2us。

2.2 测试write和read总时间

此处测试write和read管道的总时间,代码更改如下(这里是为实验三做准备):

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>int time_diff(struct timeval* t1, struct timeval* t2) {return (t2->tv_sec - t1->tv_sec) * 1000000 + (t2->tv_usec - t1->tv_usec);
}int main() {int i;char buf[] = "a";int fds[2];struct timeval curr, now;if (gettimeofday(&curr, NULL) == -1) {fprintf(stderr, "gettimeofday error\n");exit(1);}pipe(fds);for (i = 0; i < 20000; ++i) {if (write(fds[1], buf, 1) != 1) {fprintf(stderr, "read error\n");exit(1);}if (read(fds[0], buf, 1) != 1) {fprintf(stderr, "read error\n");exit(1);}}if (gettimeofday(&now, NULL) != 0) {fprintf(stderr, "gettimeofday error\n");exit(1);}printf("time elaps %d us\n", time_diff(&curr, &now));return 0;
}

测试结果如下:
在这里插入图片描述
可见在没有上下文切换的情况下,20000次的读取和写入需要11326 us。

3. 测量上下文切换成本

其原理是通过设置两个管道,第一个进程写入数据后读取数据,此时陷入阻塞,进程被挂起,切换到第二个进程,而第二个进程读取数据后,再次写入管道后自身进行读取操作进而陷入阻塞状态,系统再度切换到第一个进程执行,如此往复循环可以测试得到具体的切换成本。(多核系统注意调用sched_setaffinity函数)

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>int main() {int i;char buf[] = "a";int fds1[2], fds2[2];struct timeval begin, end;pipe(fds1);pipe(fds2);int rc = fork();if (rc == -1){fprintf(stderr, "fork error\n");exit(1);} else if (rc == 0) {close(fds1[0]);close(fds2[1]);if (gettimeofday(&begin, NULL) == -1) {fprintf(stderr, "gettimeofday error\n");exit(1);}printf("test begin at %lu s and %lu us\n", begin.tv_sec, begin.tv_usec);for (i = 0; i < 10000; ++i) {if (write(fds1[1], buf, 1) != 1) {fprintf(stderr, "read error\n");exit(1);}if (read(fds2[0], buf, 1) != 1) {fprintf(stderr, "read error\n");exit(1);}}close(fds1[1]);close(fds2[0]);exit(0);}close(fds1[1]);close(fds2[0]);for (i = 0; i < 10000; ++i) {if (read(fds1[0], buf, 1) != 1) {fprintf(stderr, "read error\n");exit(1);}if (write(fds2[1], buf, 1) != 1) {fprintf(stderr, "read error\n");exit(1);}}if (gettimeofday(&end, NULL) != 0) {fprintf(stderr, "gettimeofday error\n");exit(1);}printf("test end at %lu s and %lu us\n", end.tv_sec, end.tv_usec);close(fds1[1]);close(fds2[0]);wait(NULL);return 0;
}

测试结果如下所示:
在这里插入图片描述

系统总用时的计算公式如下:
t a l l = t s w i t c h _ a l l + t r e a d _ a n d _ w r i t e _ a l l t_{all} = t_{switch\_all}+t_{read\_and\_write\_all} tall=tswitch_all+tread_and_write_all
这其中包含20000次对管道的读取和写入以及20000次的进程切换,通过计算可得
t s w i t c h = t s w i t c h _ a l l c o u n t = t a l l − t r e a d _ a n d _ w r i t e _ a l l c o u n t t_{switch} = \frac{ t_{switch\_all}}{count} = \frac{ t_{all} - t_{read\_and\_write\_all}}{count} tswitch=counttswitch_all=counttalltread_and_write_all
最终得到切换所需要的总切换开销为26114us而单次切换的开销大约为1.3us。

这篇关于操作系统导论-课后作业-ch6的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/614791

相关文章

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

龙蜥操作系统Anolis OS-23.x安装配置图解教程(保姆级)

《龙蜥操作系统AnolisOS-23.x安装配置图解教程(保姆级)》:本文主要介绍了安装和配置AnolisOS23.2系统,包括分区、软件选择、设置root密码、网络配置、主机名设置和禁用SELinux的步骤,详细内容请阅读本文,希望能对你有所帮助... ‌AnolisOS‌是由阿里云推出的开源操作系统,旨

五大特性引领创新! 深度操作系统 deepin 25 Preview预览版发布

《五大特性引领创新!深度操作系统deepin25Preview预览版发布》今日,深度操作系统正式推出deepin25Preview版本,该版本集成了五大核心特性:磐石系统、全新DDE、Tr... 深度操作系统今日发布了 deepin 25 Preview,新版本囊括五大特性:磐石系统、全新 DDE、Tree

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

Linux操作系统 初识

在认识操作系统之前,我们首先来了解一下计算机的发展: 计算机的发展 世界上第一台计算机名叫埃尼阿克,诞生在1945年2月14日,用于军事用途。 后来因为计算机的优势和潜力巨大,计算机开始飞速发展,并产生了一个当时一直有效的定律:摩尔定律--当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会增加一倍,性能也将提升一倍。 那么相应的,计算机就会变得越来越快,越来越小型化。

1、简述linux操作系统启动流程

1、简述linux操作系统启动流程 启动第一步--加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它。这是因为BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、PnP特性等等。开机时将ROM中的指令映射到RAM的低地址空间,CPU读取到这些指令,硬件的健康状况进行检查,按照BIOS中设置的启

操作系统是怎么为不同的程序分配所需的内存空间的

操作系统为不同的程序分配内存空间的过程涉及多个关键步骤,确保每个程序都有其所需的内存资源,同时避免程序之间的冲突。以下是操作系统如何为程序分配内存空间的详细过程: 1. 内存管理的基础概念 虚拟内存:现代操作系统使用虚拟内存机制来为程序提供隔离的内存空间。每个程序运行在其独立的虚拟地址空间中,这使得程序间的内存互不干扰。物理内存:实际的 RAM(随机存取存储器),由操作系统和硬件共同管理。虚拟

C语言程序与设计第四版课后习题 - 1~8章大合集

前言 本文章是一个大合集,按照课后习题的命名方式命名,方便寻找,只需要在目录上点相对应的题号即可在这里插入图片描述 第一章课后习题 1.1 编写一个C程序 题目概述: 请参照本章例题,编写一个C程序,输出一下信息: *****************************Very good!***************************** 代码实现: #define

Java高级Day38-网络编程作业

112.网络编程作业 //1.使用字符流的方式,编写一个客户端程序和服务器端程序//2.客户端发送"name",服务器端接收到后,返回"我是nova"//3.客户端发送"hobby",服务器端接收到后,返回"编写java程序"//4.不是这两个问题,回复"你说啥呢"​​===============//客户端//===============public class SocketT

操作系统安全保护

操作系统安全概述 概念:满足安全策略要求,具有响应安全机制及安全功符合特定安全标准,在一定约束条件下 能抵御常见网络安全威胁,保障自身安全运行及资源安全 安全等级:根据安全功能和安全保障要求分为 用户自主保护级  系统审计保护级 安全标记保护级 结构化保护级 访问验证保护级 操作系统作用: 负责计算系统的资源管理、支撑和控制各种应用程序运行,为用户提供计算机系统管理接口 是构成网络信息