操作系统实验报告Word文件下载.docx
《操作系统实验报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告Word文件下载.docx(33页珍藏版)》请在冰豆网上搜索。
表示当前的程序代码是待父进程所要执行的。
父进程调用fork()创建子进程2.当创建进程不成功(fork()返回值等于-1)时,循环创建进程,直至进程创建成功。
如果fork返回值为0,则表示当前进程是子进程2,显示字符“C”;
如果fork()返回值大于0,则表示当前进程是父进程,输出字符“A”。
因为在创建子进程2的时候,fork的返回值是0还是大于0是不确定。
所以字符“A”和字符“C”的显示顺序不确定。
进程控制
一.实验目的:
修改已编写的程序,将每个进程的输出由单个字符改为一个字符串,再观察程序的执行时屏幕上出现的现象,并分析原因。
二.源代码:
#include<stdio.h>
{intp1,p2,i;
While((p1=fork())==-1);
If(p1==0)
For(i=0;
i<
500;
i++)
Printf("child%d/n",i);
else
While((p2=fork())==-1);
if(p2==0)
for(i=0;
printf("son%d\n",i)
for(i=0;
printf("daughter%d\n",i);
}
return0;
3.
实验结果:
四.实验分析:
由于函数Printf()输出的字符串之间不会被中断。
因此,字符串内部的字符顺序输出时不变。
看实验结果可以发现:
child中的各个标号是顺序的。
由于进程并发执行时的调度顺序和父子进程的抢占处理机问题,输出字符串的顺序和先后随着执行的不同而发生变化。
可以发现:
child,daughter,son的顺序是随机的。
进程的管道通信
编制一段程序,实现进程管道通信。
使用系统调用pipe()建立一条管道。
两个子进程P1和P2分别向管道各写一句话。
再观察程序的执行时屏幕上出现的现象,并分析原因。
#include<unistd.h>
#include<signal.h>
intpid1,pid2;
main()
{intfd[2];
CharOutPipe[100],InPipe[100]
Pipe(fd);
//创建管道
while(pip1=fork())==-1);
if(pip1==0)
Lock(fd[1],1,0);
//锁定管道
sprintf(OutPipe,“child1processissendingmessage!
”);
Write(fd[1],OutPipe,50);
//向管道写入数据
Sleep(5);
//等待5秒
Lockf(fd[1],0,0);
//解除管道锁定
Exit(0);
While((pip2=fork())==-1);
if(pip2==0)
{Lock(fd[1],1,0);
sprintf(OutPipe,“child2processissendingmessage!
Write(fd[1],OutPipe,50);
等待5秒
Else
{wait(0);
Read(fd[0],inpipe,50);
Printf(“%s\n”,inpipe)
Wait(0);
Read(fd[0],inpipe,50);
Exit(0);
}
四.实验分析:
Pipe()函数用于创建一个管道,正确返回0,调用成功;
错误返回-1,调用失败。
首先使用系统调用pipe()建立一条管道,调用Fork()函数创建一个子进程p1.当创建进程不成功时,循环创建进程,直至进程创建成功。
如果fork()返回值为0,则表示当前进程是子进程,向管道写一句话“child1processissedingmessage!
”;
父进程调用fork()创建子进程P2。
当创建进程不成功时,循环创建进程,直至进程创建成功。
向管道写“child2processissendingmessage!
”。
由父进程读取管道内的内容,将子进程输入到管道内的内容输出到控制台上。
消息通信
1.实验内容:
编写一段程序,同时父进程创建两个子进程p1和p2;
并使子进程p1与子进程p2通过消息队列相互发送消息(512字节)。
二.实验目的:
系统了解linux系统的通信机构IPC,掌握IPC中消息通信机制,理解消息通信的方法及特征。
三.实验要求:
(1)掌握系统调用msgget()、msgsnd()、msgrev()、msgctl()的使用方法及其功能,理解消息通信原理;
(2)系统理解linux的三种通信机制。
四.源代码:
#include<
sys/types.h>
sys/ipc.h>
sys/msg.h>
stdio.h>
#defineMSGKEY35
structmsgform
{longmtype;
charmtext[512];
};
{structmsgformmsg1,msg2;
intmsgqid,pid,*pint,p=0,p1,p2,pp=0;
while((p1=fork())==-1);
if(p1==0)
{msgqid=msgget(MSGKEY,0777|IPC_CREAT);
pid=getpid();
//printf("
111%d\n"
pid);
pint=(int*)msg1.mtext;
*pint=pid;
msg1.mtype=1;
msgsnd(msgqid,&
msg1,512,0);
sleep
(1);
msgrcv(msgqid,&
msg1,512,2,0);
pp=*pint;
printf("
receivefromp2%d\n"
pp);
//sleep
(1);
{while((p2=fork())==-1);
if(p2==0){msgqid=msgget(MSGKEY,0777|IPC_CREAT);
msg2,256,1,0);
pint=(int*)msg2.mtext;
p=*pint;
receivefromp1%d\n"
p);
msg2.mtype=2;
*pint=getpid();
222%d\n"
getpid());
msg2,256,0);
}
sleep
(1);
msgctl(msgqid,IPC_RMID,0);
5.实验结果:
6.实验分析:
Linux系统的进程通信机构(IPC)允许在任意间大批量地交换数据。
程序中由父进程创建两个子进程p1和p2通过系统调用msgget(),msgrev(),及msgct1()以使进程p1与子进程p2通过消息队列相互发送和接受消息。
进程调度算法
1.实验目的:
安装VC++6.0软件。
用VC+6.0创建一个控制台应用程序。
编程创建一系列的进程并放
入就绪队列中(使用链表实现),来模拟进程创建。
把创建的进程的信息在屏幕上显示出来。
设计进程调度程序模拟两种以上调度算法(时间片调度、优先级调度)。
进程调度程序从活动就绪队列中挑选进程,若队列为空,应显示相应提示信息。
必须有出错处理
2.进程调度算法思想:
1)时间片轮转调度(RR)
将处于就绪队列的进程按到达的时间来排序。
进程调度总是选择队列中的第一个进程(即按先来先服务)占有CPU,但每个进程占有相同的时间片。
2)优先级调度(priority)
按照进程的优先级大小来调度,使高优先级的进程优先得到处理的调度策略。
(进程的优先级大小可由系统自动地按照一定的原则赋给它。
3.实验要求:
1)由键盘输入要创建的进程数,每个进程的名称和优先数(优先数越大,优先级越高)和每个进程需要使用的CPU时间。
2)把创建的进程的信息在屏幕上显示出来。
3)由键盘输入时间片的大小。
4)在屏幕上输出两种调度算法的调度结果
4.源代码:
#include<
#include"
string.h"
voidmain(){
inti,j,k,m,max,flag,s;
intcount[100];
//RR算法循环显示次数
intt;
//时间片
intnum;
//进程数
intno[10];
//进程ID
charname[100][100];
//进程名称
charc[100];
inttime[100];
//使用CPU时间
inttim[100];
intpriority[100];
//优先数
intpri[100];
请输入你要创建的进程数:
"
);
scanf("
%d"
&
num);
\n\n"
for(i=0;
num;
{
printf("
请输入进程的名称:
scanf("
%s"
c);
strcpy(name[i],c);
请输入进程使用的CPU的时间(s):
k);
time[i]=k;
请输入进程的优先数(优先数越大,优先级越高):
priority[i]=k;
\n"
no[i]=i;
进程ID号\t进程名称\t需要CPU时间按\t优先数\n"
%d\t\t"
no[i]);
%s\t\t"
name[i]);
time[i]);
%d\n"
priority[i]);
flag=1;
while(flag==1)
请选择进程调度算法:
(1时间片轮转;
2优先级)\n"
s);
switch(s)
{
case1:
printf("
\n请输入时间片(单位s):
scanf("
t);
时间片轮转算法RR,调度结果如下:
for(i=0;
{
count[i]=time[i]/t;
}
if(time[i]%t!
=0)
count[i]++;
max=count[0];
for(i=1;
if(max<
count[i])
max=count[i];
tim[i]=time[i];
for(m=0;
m<
max;
m++)
{
for(i=0;
{
if(tim[i]>
0)
{
if(tim[i]/t!
printf("
\t%d\t\t\t%s:
\t%d"
no[i],name[i],t);
else
no[i],name[i],tim[i]);
tim[i]=tim[i]-t;
printf("
}
}
printf("
break;
case2:
优先级调度算法,结果如下:
pri[i]=priority[i];
{
max=pri[0];
m=no[0];
for(j=0;
j<
j++)
{
if(pri[j]>
max)
{
max=pri[j];
m=no[j];
}
printf("
\t%d\n"
no[m],name[m],time[m]);
pri[m]=0;
break;
default:
Pleaseinput1or2.\n"
}
要继续么?
(1继续;
0停止)\n"
flag);
FIFO页面置换算法
一.实验目的:
例如:
进程P有5个页,进程访问页的顺序为:
1,2,3,4,1,2,5,1,2,3,4,5;
如果在内存中分配给该进程3个页面,则缺页情况如下:
1
2
3
4
5
45
×
√
页面淘汰顺序:
1,2,3,4,1,2
2.源代码:
stdafx.h"
voidmain()
{inti,j;
intk=0;
inta[12]={1,2,3,4,1,2,5,1,2,3,4,5};
//页的调度顺序
intb[3][13],c[13],p=0;
b[0][0]=9;
//C语言定义数组,其初值是不确定的
b[1][0]=9;
b[2][0]=9;
"
12;
%6d"
a[i]);
\n=========================================================================\n"
{
if(a[i]==b[0][i]||a[i]==b[1][i]||a[i]==b[2][i])
{b[0][i+1]=b[0][i];
b[1][i+1]=b[1][i];
b[2][i+1]=b[2][i];
{if(i>
2)
{c[p]=b[2][i];
p++;
b[0][i+1]=a[i];
b[1][i+1]=b[0][i];
b[2][i+1]=b[1][i];
k=k+1;
for(j=0;
13;
b[0][j]);
\n-------------------------------------------------------------------------\n"
b[1][j]);
b[2][j]);
\n缺页中断次数:
%6d\n"
k);
\n页面淘汰顺序:
p;
c[j]);
LRU页面置换算法
、
4,3,2,1,4,3,5,4,3,2,1,5;
页面
页面1
页面2
页面3
缺页
4,3,2,1,5,4,3
二.源代码:
stdio.h"
voidmax_value(intx,intcc[][2]);
//函数声明,页表处理
intr_algorithm(intcc[][2]);
//函数声明,选择页面淘汰算法
voidpage_table(intpage1,intc[5][2]);
//打印页表
{inti,j,page,row=0,col=1;
//b[row]][col],行/列指针
//记录缺页中断次数
inta[12]={4,3,2,1,4,3,5,4,3,2,1,5};
//存放页的调度顺序
intb[3][13];
//模拟内存(三个页面)
intc[5][2]={{1,0},{2,0},{3,0},{4,0},{5,0}};
//定义页表并赋初值
intd[13],p=0;
//存放页面淘汰顺序,p页面淘汰数组d的指针
b[0][0]=0;
//数组的初值不确定,0表示页面为空
b[1][0]=0;
b[2][0]=0;
//****************************页面调度处理****************************
if(a[i]==b[0][i]||a[i]==b[1][i]||a[i]==b[2][i])
//将前一列数据复制到下一列
max_value(a[i],c);
//处理页表,a[i]页面是刚被访问的页面
page_table(a[i],c);
col++;
//col指向下一列
else//页面不在内存
{if(row>
2)//row>
2表示内存已没有空闲页面
{page=r_algorithm(c);
//返回淘汰的页面page
d[p]=page;
//d[]存放被淘汰的页面
p++;
k++;
//缺页中断次数
b[0][i+1]=b[0][i];
if(b[0][i+1]==page)b[0][i+1]=a[i];
if(b[1][i+1]==page)b[1][i+1]=a[i];
if(b[2][i+1]==page)b[2][i+1]=a[i];
max_value(a[i],c);
//访问a[i]页面,i页面是刚被访问的页面
page_table(a[i],c);
else
{b[0][i+1]=b[0][i];
b[row][col]=a[i];
//a[i]页面进入内存
max_value(a[i],c);
col++;
row++;
page_ta