级操作系统实验报告Word文件下载.docx
《级操作系统实验报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《级操作系统实验报告Word文件下载.docx(18页珍藏版)》请在冰豆网上搜索。
编程程序,实现父进程创建一个子进程,返回后父子进程都分别循环输出字符串“Iamparent.”或“Iamchild.”5次,每输出一次延时1秒(sleep
(1)),然后进入下一次循环。
观察并分析运行结果。
然后将程序改为父子进程同步执行:
子进程循环输出字符串“Iamchild.”5次,然后父进程再循环输出字符串“Iamparent.”5次。
再次观察并分析运行结果。
【实验步骤及实验结果分析】
⒈实验内容1
通过进程实现及验证父进程及子进程的id号的命令
ps-lg
⒉实验内容2
⑴实现父进程创建一个子进程,返回后父子进程都分别循环输出字符串“Iamparent.”或“Iamchild.”5次,每输出一次延时1秒(sleep
(1)),然后进入下一次循环。
#include<
sys/types.h>
unistd.h>
stdio.h>
intmain()
{
pid_tpt;
printf("
Helloworld!
\n"
);
inti;
pt=fork();
for(i=0;
i<
5;
i++)
{
if(pt==-1)
printf("
Forkerror.\n"
elseif{
Iamaparent.\n"
Sleep
(1);
}
else{
Iamachild.\n"
return0;
⑵父子进程同步执行:
elseif{
else{
}
【思考题】
⒈程序和进程的区别。
(1)程序是动态的,程序是静态的:
程序是有序代码的集合;
进程是程序的执行。
通常进程不可在计算机之间迁移;
而程序通常对应着文件、静态和可以复制。
(2)进程是暂时的,程序是永久的:
进程是一个状态变化的过程,程序可长久保存。
(3)进程和程序的组成不同:
进程的组成包括程序、数据和进程控制块(即进程状态信息)。
(4)进程和程序的对应关系:
通过多次执行,一个程序可对应多个进程;
通过调用关系,一个进程可包括多个程序。
⒉Linux操作系统下有哪些进程类型。
交互进程;
批处理进程;
守护进程;
⒊进程创建函数fork和vfork的区别。
(1)fork()用于创建一个新进程。
由fork()创建的子进程是父进程的副本。
即子进程获取父进程数据空间,堆和栈的副本。
父子进程之间不共享这些存储空间的部分。
而vfork()创建的进程并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec(或exit)于是也就不会存放该地址空间。
相反,在子进程调用exec或exit之前,它在父进程的空间进行。
(2)vfork()与fork()另一个区别就是:
vfork保证子进程先运行,在调用exec或exit之前与父进程数据是共享的,在它调用exec或exit之后父进程才可能被调度运行。
(3)vfork和fork之间的还有一个区别是:
vfork保证子进程先运行,在她调用exec或exit之后父进程才可能被调度运行。
如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。
⒋进程的退出函数有哪些?
有何区别?
C程序是如何被启动终止的?
exit函数;
return函数;
abort函数_exit函数。
exit和_exit函数用于正常终止一个程序
exit先执行一些清除处理.然后进入内核清除操作包括调用执行各终止处理程序,关闭所有标准I/O流
_exit立即进入内核
abort函数用于异常终止一个程序
exit是一个函数,有参数,把控制权交给系统
return是函数执行完后的返回,将控制权交给调用函数
实验二进程通信
⒈了解基于信号的进程通信机制。
⒉熟悉LINUX系统中进程之间软中断通信的基本原理。
一、信号
⒈信号的基本概念
⒉信号的发送
⒊对信号的处理
二、所涉及的中断调用
⒈kill()
⒉signal()
⒊wait()
⒋waitpid()
⒌lockf()
⒈带Linux操作系统的PC机
⒉GCC编译器
⒈编写程序:
用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按^c键);
捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:
Childprocess1iskilledbyparent!
Childprocess2iskilledbyparent!
父进程等待两个子进程终止后,输出如下的信息后终止:
Parentprocessiskilled!
⒉分析利用软中断通信实现进程同步的机理。
⒉对软中断信号的处理分三种情况进行:
(1)如果进程收到的软中断是一个已决定要忽略的信号,不做处理便立即返回。
(2)进程收到软中断后便退出。
(3)执行用户设置的软中断处理程序。
实验内容的参考程序如下,请仔细阅读、调试、分析,回答下述问题:
#include<
signal.h>
stdlib.h>
sys/wait.h>
voidwaiting(),stop();
intwait_mark;
intmain()
intp1,p2,stdout=1;
while((p1=fork())==-1);
/*创建子进程p1*/
if(p1>
0)
{
while((p2=fork())==-1);
/*创建子进程p2*/
if(p2>
{
wait_mark=1;
signal(SIGINT,stop);
/*接收到^c信号,转stop*/
waiting();
kill(p1,16);
/*向p1发软中断信号16*/
kill(p2,17);
/*向p2发软中断信号17*/
wait(0);
/*同步*/
printf("
exit(0);
}
else
signal(17,stop);
/*接收到软中断信号17,转stop*/
lockf(stdout,1,0);
Childprocess2iskilledbyparent!
lockf(stdout,0,0);
}
else
wait_mark=1;
signal(16,stop);
/*接收到软中断信号16,转stop*/
waiting();
lockf(stdout,1,0);
printf("
Childprocess1iskilledbyparent!
lockf(stdout,0,0);
exit(0);
return0;
voidwaiting()
while(wait_mark!
=0);
voidstop()
wait_mark=0;
⒈参考程序段前面部分用了两个wait(0),它们起什么作用?
作用:
wait(0)函数作用是等待子进程结束,父进程有两个子进程,所以两个wait函数。
⒉参考程序段中每个进程退出时都用了语句exit(0),为什么?
是为了让子进程正常自我终止,正常退出。
⒊参考程序的运行结果是什么?
⒋参考程序是否符合实验要求?
为什么?
不符合。
原因:
p1,p2都会捕捉中断信号。
对于父进程,当它捕捉到中断信号时就会转向指定的函数stop();
函数,之后父进程被唤醒,从被中断处继续执行。
对于子进程,由于没有给它们指定的收到中断信号后的动作,就会执行默认的动作,结束自己。
所以当我们发出中断信号后,父进程按预计的方式正常执行,而p1,p2自己结束了自己,所以不会有预计的结果。
⒌参考程序该如何修改才能得到正确结果?
第一种方法:
在fork()语句创建子进程之前捕捉中断信号,既signal(SIGINT,stop);
。
第二种方法:
在每个子进程前添加忽略中断信号的语句,既signal(SIGINT,SI
G_IGN);
第三种方法:
打开两个界面,一个界面正常编译,另一个界面执行:
ps-a
ps-a|grepa.out
kill-sINT11313
实验三内存管理
⒈了解虚拟存储技术的特点。
⒉掌握请求页式存储管理的页面置换算法。
3.了解页面大小和内存实际容量对命中率的影响。
分页存储管理将一个进程的逻辑地址空间分成若干大小相等的片,成为页面或页。
在进程运行过程中,若其所要访问的页面不在内存而需要把他们调入内存,但内存已无空闲时,为了保证该进程能正常运行,系统必须从内存中调出一页程序或数据,送磁盘的对换区中。
但应将哪个页面调出,须根据一定的算法来确定。
通常,把选择换出页面的算法称为页面置换算法(PageReplacementAlgorithm)。
一个好的页面置换算法,应具有较低的页面更换频率。
从理论上讲,应将那些以后不再会访问的页面换出,或将那些在较长时间内不会再访问的页面调出。
⒈最佳置换算法OPT(Optimal)
⒉先进先出页面置换算法FIFO
⒊最近最久未使用置换算法LRU
⒋最少访问页面置换算法LFU
⒌最近最不经常使用算法NUR
⒈带Linux操作系统的PC机。
⒉GCC编译器。
1、通过随机数产生一个指令序列,共320条指令。
指令的地址按下述原则生成:
●50%的指令是顺序执行的
●25%的指令是均匀分布在前地址部分
●25%的指令是均匀分布在后地址部分
具体的实施方法是:
●在【0,319】的指令地址之间随机选取一起点m;
●顺序执行一条指令,即执行地址为m+1的指令;
●在前地址【0,m+1】中随机选取一条指令并执行,该指令的地址为m’;
●顺序执行一条指令,其地址为m’+1;
●在后地址[m’+2,319]中随机选取一条指令并执行;
●重复上述步骤,直到执行320次指令。
2、将指令序列变换成为页地址流
设:
●页面大小为1K;
●用户内存容量为4页到32页;
●用户虚拟容量为32K。
在用户虚存中,按每K存放10条指令排列虚拟地址,即320条指令在虚存中的存放方式为:
第0条~第9条指令为第0页(对应虚存地址为【0,9】);
第10条~第19条指令为第1页(对应虚存地址为【10,19】);
…
第310条~第319条指令为第31页(对应虚存地址为【310,319】)。
按以上方式,用户指令可组成32页。
3、计算并输出下列各种算法在不同内存容量下的命中率。
●先进先出的算法(FIFO);
●最近最少使用算法(LRU);
●最佳淘汰算法(OPT):
先淘汰最不常用的页地址;
其中OPT为选作内容。
命中率=1–页面时效次数/页地址流长度
在本实验中,页地址流长度为320,页面失效次数为每次访问相应指令时,该指令所对应的页不在内存的次数。
首先用srand()和rand()函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。
//****利用先进先出算法(FIFO)和最近最久未使用算法(LRU)****//
string.h>
#defineNULL_110000
constintty=320;
intd[320];
//指令序列
intpage[320];
//页地址流
intp[32];
//内存页面
intque;
//缺页次数
inttime[32];
//记录页面距离上次被访问的时间
voidcreat(intleng)//leng为内存页面数量
que=0;
leng;
p[i]=NULL_1;
//让内存页面置空
time[i]=0;
//******先进先出算法
voidFIFO(intleng)//leng为内存页面数量
inti,j,k;
intn;
//n为要被替换的页面号,按0,1,2...leng,0,1,2...leng循环变化
creat(leng);
//初始化内存页面
n=0;
for(i=0;
ty;
k=0;
for(j=0;
j<
j++)
if(p[j]==NULL_1)
break;
elseif(p[j]==page[i])//在内存中有该页
{
k=1;
break;
}
if(k==0)
que++;
p[n]=page[i];
n++;
if(n==leng)
n=0;
%-7.3f\t"
1-(float)que/ty);
//******最近最久未使用算法
voidLRU(intleng)//leng为内存页面数量
inti,j,k;
inttmax;
//存time的最大值
intt;
//t为要被访问的页面号
creat(leng);
k=0;
for(j=0;
if(p[j]==NULL_1)
elseif(p[j]==page[i])//在内存中有该页
k=1;
t=j;
if(k==0)
tmax=time[0];
t=0;
j++)//查找最久没访问的页面号赋予t
if(tmax<
time[j])
tmax=time[j];
t=j;
p[t]=page[i];
j++)//将每个页面time自增
time[j]++;
time[t]=0;
//将这次被访问的页面time清零
%-7.3f\t"
voidmain()
intm,i;
srand(10*getpid());
//用来作为初始化随机数队列的"
种子"
m=(int)((float)(ty-1)*(rand()/(RAND_MAX+1.0)));
//选0-319中一数
for(i=0;
i<
i+=4)//产生指令队列
d[i]=m;
//任选一指令访问点m
d[i+1]=d[i]+1;
//顺序执行一条指令m+1
d[i+2]=(int)((float)d[i]*(rand()/(RAND_MAX+1.0)));
//执行前地址指令m'
即选择(0,m+1)之间的数
d[i+3]=d[i+2]+1;
//顺序执行一条指令
m=(int)((float)((ty-1)-d[i+2])*(rand()/(RAND_MAX+1.0)))+d[i+2];
//选(m'
+2,319)之间数
i++)//将指令序列变换成页地址流
page[i]=d[i]/10;
PAGE\tFIFO\tLRU\t\n"
for(i=4;
=32;
i++)//内存从4页到32页
%2d\t"
i);
FIFO(i);
LRU(i);
程序运行结果:
⒈在内存页面较少(4~5个)的情况时,各种页面置换算法的命中率有何差别?
FIFO算法和LRU算法命中率都在55%左右,相差不大。
⒉在内存页面为7~12个页面时,各种页面置换算法的命中率有何差异?
FIFO算法命中率在59%-67%,LRU算法命中率在60%-70%之间,相对来说,最近最久未使用算法效率更好一些。
⒊在内存页面为25~32个页面时,各种页面置换算法的命中率有何差异?
两种算法命中率都在80%-90%之间,当内存中中页面数逐渐增加时,访问的都已装入内存,从而命中率都较大。
实验四文件系统
1、熟悉Linux文件系统的文件和目录结构,掌握Linux文件系统的基本特征。
2、掌握命令行方式下文件操作命令和程序中文件操作函数的使用方法。
3.、掌握Linux文件系统的加载和卸载方法。
1、带Linux操作系统的PC机
2、GCC编译器
1.熟悉Linux下的文件操作命令,如查看文件系统的分区和设备文件、查看文件系统目录结构、创建文件夹、复制文件、更改文件权限等,观察Linux文件系统的特点。
2.对比实验一的文件拷贝代码,利用不同的文件操作函数实现文件的输出和拷贝。
3.实现对光盘的加载和访问,然后卸载设备。
4.加载Windows文件系统,实现对Windows数据的访问和共享。
实验内容:
1.df:
查看文件系统的状态信息,显示各分区容量、硬盘占用空间、目前剩余空间及挂载点等信息
du:
统计目录或文件所占磁盘空间的大小
mkdir:
创建文件夹
cp:
复制文件
chmod:
更改文件权限
2.
(1)#include<
#include<
FILE*fp;
charch;
charfname[30];
Pleaseinputthefilename:
"
scanf("
%s"
&
fname);
fp=fopen(fname,"
r"
if(fp==NULL)
Can’topenthefile!
while((ch=getc(fp))!
=EOF)
{putchar(ch);
fclose(fp);
(2)#include<
unistd>
FILE*fp=NULL;
FILE*fq=NULL;
fq=fopen("
/root/c_code/test/t.c"
"
a"
fp=fopen("
/etc/passwd"
)//打开文件
while((ch=fgetc(fp))!
=EOF)