大连理工大学
本科实验报告
课程名称:操作系统实验
学院(系):计算机科学与技术学院
专 业: 计算机科学与技术
班 级: 电计
学 号:
学生姓名:
实验项目列表
实验项目名称
学时
成 绩
指导教师
序号
预习
操作
结果
1
进程管理
2
存储管理
3
磁盘移臂调度
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
总计
学分:
大连理工大学实验报告
学院(系):计算机科学与技术学院 专业: 计算机科学与技术 班级:电计1301
姓 名: 学号: 组:
实验时间: 201663 实验室: 综412 实验台:
指导教师签字: 成绩:
进程管理实验
一、 实验目的加深对于进程并发执行概念的理解。实践并发进程的创建和控制方 法。观察和体验进程的动态特性。进一步理解进程生命期期间创建、变换、 撤销状态变换的过程。掌握进程控制的方法,了解父子进程间的控制和协 作关系。练习Linux系统中进程创建与控制有关的系统调用的编程和调试 技术。
二、 实验原理和内容
原理:
(1) fork成功创建子进程后将返回子进程的进程号,不成功会返回-1
(2) exec系统调用有一组6个函数,其中示例实验中引用了 execve
系统调用语法:
int execve(c onst char *path, const char *argv[], const char
envp[]);
envp[]);
path要装入的新的执行文件的绝对路径名字符串 argv[]要传递给新执行程序的完整的命令参数列表(可以为空).
en vp[]要传递给新执行程序的完整的环境变量参数列表 (可以为
空).Exec执行成功后将用一个新的程序代替原进程, 但进程号不
变,它绝不会再返回到调用进程了。exec调用失败,它会返回-1。
内容:
(1)每个进程都执行自己独立的程序,打印自己的 pid,每个父进程打印
(2)每个进程都执行自己独立的程序,打印自己的 pid,父进程打印其子
(3)进程的pid;
(3)
编写一个命令处理程序,能处理max(m, n), min(m,n)和
average(m,n,l)这几个命令。(使用exec函数族)
三实验代码及结果
(1)
#i nclude<stdio.h> int main()
if(fork() == 0)
{
printf(” 子进程的 pid 为:%d.\n",getpid());
if(fork() == 0)
{
printf("二级子进程的 pid 为:%d.\n",getpid());
}
}
else {
printf("父进程的 pid 为%d.\n",getpid());
}
return 0;
}
运行结果:
lenouoeiDEfl-PG ?
父进桓的Md为IM测?予进程的pi(i为t 4024,
lfenowo@lDEfi-PC ~
5二级子进程的嗣为;^712.
(2)
#i nclude<stdio.h>
int main()
if(fork() == 0) {
printf("子进程的 pid 为 %d.\n",getpid());
}
else
{
if(fork() == 0)
{
printf("子进程 2 的 pid %d.\n",getpid());
}
else printf("父进程的 pid 为 %d.\n\n",getpid());
}
}
return 0;
leno^ti@[DEn-PC 冋 $ SfQG 1—2 wG —Q 2
lenovo@IDEO—PC ?
$ _Z2_e?e
子进唱的卩訳为5436?
交进粗的Did为13236.子进程2的卩込113-14.
调用函数为:
include <unistd.h>
#include <string.h>
#include <stdio.h>
#define N 10
int main()
{
int i;
char cmdname[N];
printf("$ ");
scanf("%s",cmdname); if(strcmp(cmdname,"min")==0)
{
execl("/home/lenovo/min","min",NULL);
}
else if(strcmp(cmdname,"max")==0)
{
execl("/home/lenovo/max","max",NULL); }
else if(strcmp(cmdname,"ave")==0)
execl("/home/lenovo/average","ave",NULL);
else
printf(" \n"j; ? o!
return 0;
}
Max 函数为:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int a,b;
printf(" 请输入要比较的两个数: \n");
scanf("%d%d",&a,&b);
printf(" 大的数是: %d\n",a>b?a:b);
}
Min 函数为:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
int a,b;
printf(" 请输入要比较的两个数: \n");
scanf("%d%d",&a,&b);
printf(" 小的数是: %d\n",a<b?a:b);
}
Average 函数为:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
float a,b,c;
\n");printf(" 请输入要求平均值的两个数: scanf("%f%f%f",&a,&b,&c);
\n");
printf(" 平均值为: %.3f\n",(a+b+c)/3);
}
实验结果为:
]enouo(?IDEfi-PC M
$ ?/3_exe
$
请输入要比较的两个数:
23 4b
大的数是."
lenovu GIDEfi-PC *
$ ?”3?exe
$ min
请输入要比较的两个数’
23 46
小的数是23
lenouo(?IDEft-PC ?
$ . /2.exe
专ave
倩输入要求平均值的两个数’
1? 26 37
(此处文字打错,实际输入三个数)梓均值为’ 27.333
(此处文字打错,实际输入三个数)
四实验总结
本次实验熟悉了用cygwin软件模拟linux系统的编译环境,熟悉了编 译语句gcc 1.c -o 1和执行语句./l.exe的使用。并且编程实现了 fork成 功创建子进程及父子进程间的关系,比如 else则代表父进程,比如二级子
进程的建立方法。
大连理工大学实验报告
学院(系):计算机科学与技术学院 专业: 计算机科学与技术 班级:电计1301
姓 名: 学号: 组:
实验时间: 201663 实验室: 综412 实验台:
指导教师签字: 成绩:
存储管理实验
实验目的加深对于存储管理的了解,掌握虚拟存储器的实现原理;观察和了解 重要的页面置换算法和置换过程。练习模拟算法的编程技巧,锻炼分析试 验数据的能力。
实验内容
示例实验程序中模拟两种置换算法: LRU 算法和 FIFO 算法。
能对两种算法给定任意序列不同的页面引用串和任意页面实内存数目的 组合测试,显示页置换的过程。
能统计和报告不同置换算法情况下依次淘汰的页号、缺页次数(页错误 数)和缺页率。
实验代码及结果
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int a[100],b[100];// 执行页号序列、主存中的队列
int len;// 序列长度
int n;// 引用页面号的个数 0~n-1
int m;// 内存中可容纳页面数目
int no;// 缺页次数
float qyl;// 缺页率
int front,rear;
int check(int x)// 检查队列中是否有该页号
int j;
for(j=front;j<=rear;j++)
{
if(b[j]==x) return 1;
}
return 0;
}
int find(int i)// 寻找队列中最近最少使用的页号,仅 lrU 算法使用该函数 {
int j,k,small=100,x,count=0;
int flag[100];// 标记这个数是否在最近使用的 m 个数中 memset(flag,0,sizeof(flag));
for(k=i-1;k>=0;k--)
{
if(flag[a[k]]==0)
{
flag[a[k]]=1;
count++;
if(count==m)
for(j=front;j<=rear;j++)
if(b[j]==a[k]) return j;
}
}
}
}
return x;
}
void FIFO()// 先进先出算法
{
int i,j;
front=rear=0;
no=0;
b[front]=a[0];
printf("%d 无淘汰 缺页加 1\n",b[front]);
no+=1;
for(i=1;i<len;i++)
{
if((rear-front+1)<m)// 内存页数未满
{
if(check(a[i])==0)// 检测到队列中没有该页号
{
b[++rear]=a[i];
for(j=front;j<=rear;j++)
printf("%d ",b[j]);
printf(" 无淘汰 缺页加 1\n");
no+=1;
}
else if(check(a[i])==1)// 检测到队列中有该页号
{
for(j=front;j<=rear;j++)
printf("%d ",b[j]);
printf(" 无淘汰 不缺页 \n");
}
}
else if((rear-front+1)==m)// 内存页数已满
{
if(check(a[i])==0)// 检测到队列中没有该页号
{
b[++rear]=a[i];
front+=1;
for(j=front;j<=rear;j++)
printf("%d ",b[j]);
printf(" 淘汰页号 %d 缺页加 1\n",b[front-1]);
no+=1;
else if(check(a[i])==1)// 检测到队列中有该页号
{
for(j=front;j<=rear;j++)
printf("%d ",b[j]);
printf(" 无淘汰 不缺页 \n");
}
}
}
qyl=(float)no/(float)len;
printf(" 序列长度: %d 缺页次数: %d 缺页率: %.2f\n",len,no,qyl); }
void LRU()// 最近最少使用算法
{
int i,j,temp;
front=rear=0;
no=0;
b[front]=a[0];
printf("%d 无淘汰 缺页加 1\n",b[front]);
no+=1;
for(i=1;i<len;i++)
{
if((rear-front+1)<m)// 内存页数未满时,策略和 FIFO 相同
{
if(check(a[i])==0)// 检测到队列中没有该页号
{
b[++rear]=a[i];
for(j=front;j<=rear;j++)
printf("%d ",b[j]);
printf(" 无淘汰 缺页加 1\n");
no+=1;
}
else // 检测到队列中有该页号
{
for(j=front;j<=rear;j++)
printf("%d ",b[j]);
printf(" 无淘汰 不缺页 \n");
}
}
FIFO 不同else if((rear-front+1)==m)//
FIFO 不同
{
if(check(a[i])==0)// 检测到队列中没有该页号
temp=b[find(i)];
b[find(i)]=a[i];// 替换掉最近最少使用的页号
for(j=front;j<=rear;j++)
printf("%d ",b[j]);
printf(" 淘汰页号 %d 缺页加 1\n",temp);
no+=1;
}
else if(check(a[i])==1)// 检测到队列中有该页号
{
for(j=front;j<=rear;j++)
printf("%d ",b[j]);
printf(" 无淘汰 不缺页 \n");
}
}
}
qyl=(float)no/(float)len;
printf(" 序列长度: %d 缺页次数: %d 缺页率: %.2f\n",len,no,qyl);
}
int main()
{
int i,choice;
printf(" 请输入序列长度、页号个数、页面实内存数目: \n");
scanf("%d%d%d",&len,&n,&m);
//for(i=0;i<len;i++) scanf("%d",&a[i]);
printf(" 随机生成页面引用串: ");
srand( (unsigned)time( NULL ) ); // 这个就是生成了一个种子
for(i=0;i<len;i++) // 循环 len 次,生成 len 个随机数
{
a[i]=rand()%n; // 通过 rand()%n 来生成一个 0~n-1 的随机数,并将它赋给 a[i] printf("%d ",a[i]);
}
printf("\n 请选择要使用的算法: 1 FIFO 2 LRU\n");
scanf("%d",&choice);
printf("\n\n");
if(choice==1) FIFO();
else if(choice==2) LRU();
}
实验结果:
I1S力力 力为勺獰汰灣汰汰淘汰汰汰汰汰1Z 饒汰淘无淘淘无淘淘海淘淘,「页页脣页页 十 n[1L?a
I
1S
力力 力为勺
獰汰灣汰汰淘汰汰汰汰汰1Z 饒汰淘无淘淘无淘淘海淘淘,
「页页脣页页 十 n[1L?a*、ntn\n\n.l 」s?s讎
如图,选择FIFO算法序列长度为12,可选页号个数为10个(即随机生成0~9的页号),
内存页数为4。页面置换过程如图,缺页11次,缺页率为0.92。
;9 2 6 3 0 8请选择要使用的算法;1 FIFO 2 LF
;9 2 6 3 0 8
请选择要使用的算法;1 FIFO 2 LF
如图,选择LRU算法,序列长度为
如图,选择LRU算法,序列长度为12 ,
号),内存页数为4。页面置换过程如图,
四实验总结
可选页号个数为10个(即随机生成0~9的页
缺页 9次,缺页率为0.75。
本次实验用C语言编程,确定序列长度、页号范围、内存中页面数目,
随机生成页号序列。可分别选择两种算法来算出置换过程及缺页情况。本 次实验使我深入的理解了 FIFO算法和LRU算法的置换过程,并且通过比 较发现,在大多数情况下LRU算法都具备更低的缺页率。
大连理工大学实验报告
学院(系):计算机科学与技术学院 专业: 计算机科学与技术 班级:电计1301
姓 名: 学号: 组:
实验时间: 201663 实验室: 综412 实验台:
指导教师签字: 成绩:
存储管理实验
一实验目的加深对于操作系统设备管理技术的了解,体验磁盘移臂调度算法的重 要性;掌握几种重要的磁盘移臂调度算法,练习模拟算法的编程技巧,锻 炼研究分析试验数据的能力。
二 实验内容
示例实验程序中模拟两种磁盘移臂调度算法: SSTF 算法和 SCAN 算法
能对两种算法给定任意序列不同的磁盘请求序列,显示响应磁盘请求的 过程。
能统计和报告不同算法情况下响应请求的顺序、移臂的总量。
三 实验代码及结果
#include <stdio.h>
#include <stdlib.h>
int cidao[20];// 要被访问的磁道序列
int biaoji[20];// 标记是否访问过
int n,sum;// 要访问的磁道个数,疑臂总量
void SSTF()
{
int i,j,k,min,now=100;//now 为当前磁头所在磁道位置
sum=0;
printf("使用SSTF算法处理:\n");
for(i=0;i<n;i++)
{
min=200;//min 的最大值可能是 0~199, 必须设为 200
for(j=0;j<n;j++)
if(abs(cidao[j]-now)<min&&biaoji[j]==0)
{
min=abs(cidao[j]-now);
k=j;
}
}
biaoji[k]=1;
sum+=abs(cidao[k]-now);
printf(" 访问: %d 移动距离: %d\n",cidao[k],abs(cidao[k]-now)); now=cidao[k];
}
printf(" 移臂总量为: %d\n",sum);
}
void SCAN()
{
int i,j,k,min,now=100;//now 为当前磁头所在磁道位置
int a=0,b;//ab 分别为大于等于 100 小于100 的磁道个数 sum=0;
printf(" 使用 SCAN 算法处理: \n");
for(i=0;i<n;i++)
if(cidao[i]>=100) a+=1;
b=n-a;
for(i=0;i<a;i++)
{
min=200;//min 的最大值可能是 0~199, 必须设为 200 for(j=0;j<n;j++)
{
if(abs(cidao[j]-now)<min&&biaoji[j]==0&&cidao[j]>=now)
{
min=abs(cidao[j]-now);
k=j;
}
}
biaoji[k]=1;
sum+=abs(cidao[k]-now);
printf(" 访问: %d 移动距离: %d\n",cidao[k],abs(cidao[k]-now)); now=cidao[k];
}
for(i=0;i<b;i++)
{
min=200;//min 的最大值可能是 0~199, 必须设为 200 for(j=0;j<n;j++)
if(abs(cidao[j]-now)<min&&biaoji[j]==0&&cidao[j]<now)
min=abs(cidao[j]-now);
k=j;
}
}
biaoji[k]=1;
sum+=abs(cidao[k]-now);
printf(" 访问: %d 移动距离: %d\n",cidao[k],abs(cidao[k]-now));
now=cidao[k];
}
printf(" 移臂总量为: %d\n",sum);
}
int main()// 默认从 100 磁道开始
{
int i;
printf(" 请输入磁道序列长度: \n");
scanf("%d",&n);
printf(" 随机生成磁道序列: ");
srand( (unsigned)time( NULL ) ); // 这个就是生成了一个种子
for(i=0;i<n;i++) // 循环 n 次,生成 n 个随机数
cidao[i]=rand()%200; // 通过 rand()%200 来生成一个 0~199 的随机数,并将它
赋给 cidao[i]
printf("%d ",cidao[i]);
}
prin tf("\n");
memset(biaoji,0,sizeof(biaoji));
SSTF();
memset(biaoji,0,sizeof(biaoji));
SCAN();
}
54 173 159 124 112 97 笳 149嘈」亠M *ZE亠_?亠云
54 173 159 124 112 97 笳 149
嘈」亠M *ZE亠_?亠云劣
2 4 9- ? 3e-t一-_ s
s *
禺离离离离s:
n =□_-n--n = n_ 雀
8 8
s 0 ■ >
-动罷处
2 4 9 ? 8
tN 0 i 5 4 5 7 8 7 3 4 ?总&G
ft- 4
1 5
离离高离离离离5: ±n_-n = n = n_-n_-n = n_ 丄动动动动动动动
- -1 ■ J ■ i .亠-K亠K十齐耒土严多多多
离离离
巨巨巨
8 88 2
动动动淞
r?.
如图,输入磁道数量10,随机生成访问磁道的序列188 102 54 173 159 134 112 97 93 149,范围在0~199之间。同时用两个算法对这个序列处理,“访问”即为访问磁道的 顺序,最后SSTF算法移臂总量240, SCAN算法移臂总量222。两个算法移臂总量差 距不大,对于某些序列二者的移臂总量相同。
实验总结
本次实验使用C语言模拟了访问磁道顺序的算法,初始位置设为 100 , 随机生成了 0~199的序列,用SSTF和SCAN算法处理,对于大多数序列, SCAN 要比 SSTF 算法节省移臂总量, 但节省得不算太多, 对于某些序列二 者的移臂总量会出现相同的情况,使我深入理解了这两个算法以及比较出 了算法之间的优劣。