}
return0;
}
拓展点:
五状态模型
四、实验结果(截图)
创建进程:
状态running✍ready:
状态running✍blocked:
状态blocked✍ready:
创建新进程:
情况一有进程正在运行
情况二无进程正在运行
终止进程:
实验三进程同步和通信
一、实验目的
调试、修改、运行模拟程序,通过形象化的状态显示,使学生理解进程的概念,了解同步和通信的过程,掌握进程通信和同步的机制,特别是利用缓冲区进行同步和通信的过程。
通过补充新功能,使学生能灵活运用相关知识,培养创新能力。
二、实验原理
假定.缓冲区可以容纳8个数据;
因为缓冲区是有限的,因此当其满了时生产者进程应该等待;当消费者取走一个数据后,应唤醒正在等待的生产者进程;
当缓冲区空时,消费者进程应该等待;当生产者向缓冲区放入了一个数据时,应唤醒正在等待的消费者进程。
这就是生产者和消费者之间的同步
三、实验内容(源码、注释、基础内容、扩展点等)
基础内容:
编写程序使其模拟两个进程,即生产者(producer)进程和消费者(Consumer)进程工作;生产者每次产生一个数据,送入缓冲区中;消费者每次从缓冲区中取走一个数据。
每次写入和读出数据时,都将读和写指针加一。
当指针到达缓冲区尾,重新将指针退回起点;
/***************************************************************/
/*PROGRAMNAME:
PRODUCER_CONSUMER*/
/*Thisprogramsimulatestwoprocesses,producerwhich*/
/*continuestoproducemessageandputitintoabuffer*/
/*[implementedbyPIPE],andconsumerwhichcontinuestoget*/
/*messagefromthebufferanduseit.*/
/*Theprogramalsodemonstratesthesynchronismbetween*/
/*processesandusesofPIPE.*/
/***************************************************************/
#include<>
#include<>
count>=8:
toomanyprodecers;<=0:
toomanyconsumers
intcount=0;
intcountp=0,countr=0;
main()
{
intoutput,ret,i;ame="Producer\0";
process[CONSUMER].name="Consumer\0";
process[PRODUCER].statu=process[CONSUMER].statu=READY;
process[PRODUCER].time=process[CONSUMER].time=0;
output=0;
printf("Nowstartingtheprogram!
\n");
printf("Press'p1'torunPRODUCER1,press'p2'torunPRODUCER2.\npress'c'torunCONSUMER.\n");
n");
for(i=0;i<1000;i++)
{
in[0]='N';
while(in[0]=='N')
{
scanf("%s",in);
if(in[0]!
='e'&&in[0]!
='p'&&in[0]!
='c')tatu==READY)tatu==READY)tatu==WAIT)n");
continue;
}
countp++;
printf("countp=%d\n",countp);
}
}
elseif(in[1]=='1')n");
continue;
}
countp++;
printf("countp=%d\n",countp);
}
printf("Lookout.\n");
n");
}
if(in[0]=='c'&&process[CONSUMER].statu==WAIT)n");
continue;
}
countr++;
printf("countr=%d\n",countr);
printf("Lookout!
!
!
\n");
n");
}
if(in[0]=='e')exit
(1);
prn(process,pipe,pipetb);in[0]='N';
}
}
runp(out,p,pipe,tb,t)/*runproducer*/
intout,pipe[],t;
structpcbp[];
structpipetype*tb;
{
p[t].statu=RUN;
printf("runPRODUCER.product%d",out);
if(count>=8)tatu=WAIT;
return(SLEEP);
}
tb->writeptr=tb->writeptr%8;ime++;
ime);
p[t].statu=READY;
if((tb->pointc)!
=NULL)
{
tatu=RUN;
printf("runCONSUMER.");
if(count<=0)tatu=WAIT;
return(SLEEP);
}
c=pipe[tb->readptr];
pipe[tb->readptr]=0;
tb->readptr++;
tb->readptr=tb->readptr%8;
printf("readptr=%d\n",tb->readptr);
printf("use%d",c);
count--;
printf("count=%d\n",count);
p[t].time++;
ime);
p[t].statu=READY;
if(tb->pointp!
=NULL)
{
tatu==WAIT)||countp>=1)tatu==WAIT)||countr>=1)
printf("%dCONSUMERwait",countr);
else
printf("CONSUMERready");
printf("\n");
printf("\n######################\n");
}
拓展点:
设置了等待队列的长度,并显示等待队列内部情况
四、实验结果(截图)
生产者:
情况一正常生产
情况二超过缓冲区
情况三超过等待队列
消费者:
情况一正常
情况二无产品可消费
又开始生产:
实验四进程的管道通信
一、实验目的
加深对进程概念的理解,明确进程和程序的区别;
学习进程创建的过程,进一步认识并发执行的实质;
分析进程争用资源的现象,学习解决进程互斥的方法;
学习解决进程同步的方法;
掌握Linux系统进程间通过管道通信的具体实现方法。
二、实验原理
1.基本概念:
进程的概念;进程与程序的区别;并发执行的概念
进程互斥的概念;进程通信的基本原理
2.系统调用:
设置系统调用号:
设置多条系统调用命令,并赋予每条系统调用命令一个唯一的系统调用号
处理系统调用:
OS中有一张系统调用入口表,表中每个表目对应一条系统调用命令,包含该系统调用自带参数的数目、系统调用命令处理程序的入口地址等。
OS内核便是根据所输入的系统调用号在该表中查找到相应的系统调用,进而转入它的入口地址去执行系统调用程序。
Linux的系统调用机制:
通过中断机制实现
三、实验内容(源码、注释、基础内容、扩展点等)
#include<>
#include<>
#include<>
#include
#include
intmain()
{
intpid1,pid2,pid3;
intfd[2];
charoutpipe[50],inpipe[50];
pipe(fd);
while((pid1=fork())==-1);
if(pid1==0)
{
printf("s1\n");
lockf(fd[1],1,0);
\n",diseffect/total_instruction);
printf("TheHitRateis:
%f.\n",1-diseffect/total_instruction);
return0;
}
\n",diseffect/total_instruction);
printf("TheHitRateis:
%f.\n",1-diseffect/total_instruction);
return0;
}
intFIFO4(intAcess_series[]){
intM_Frame[4];\n",diseffect/total_instruction);
printf("TheHitRateis:
%f.\n",1-diseffect/total_instruction);
return0;
}
intmain()
{
intn,m;
srand((int)time(NULL));//Initializationofrandomnumbergenerators
//Initializepageaccesssequence12345
intAcess_series[total_instruction];
for(inti=0;iAcess_series[i]=(int)rand()%5+1;
printf("TheAcess_seriesare:
\n");
for(inti=0;iprintf("%d",Acess_series[i]);
printf("\n");
//Create2childprocesses
intp1,p2,fd[2];
if((p1=fork())==0)
{
if((p2=fork())==0)
{
LRU(Acess_series);
sleep
(2);
exit(0);
}
else
{
FIFO3(Acess_series);
FIFO4(Acess_series);
sleep
(2);
exit(0);
}
}
else
exit(0);
return0;
}
拓展点:
能显示每次的命中情况
一、实验结果(截图)
会出现Belady现象: