作业实验13DOC.docx

上传人:b****4 文档编号:11596273 上传时间:2023-03-19 格式:DOCX 页数:15 大小:19.16KB
下载 相关 举报
作业实验13DOC.docx_第1页
第1页 / 共15页
作业实验13DOC.docx_第2页
第2页 / 共15页
作业实验13DOC.docx_第3页
第3页 / 共15页
作业实验13DOC.docx_第4页
第4页 / 共15页
作业实验13DOC.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

作业实验13DOC.docx

《作业实验13DOC.docx》由会员分享,可在线阅读,更多相关《作业实验13DOC.docx(15页珍藏版)》请在冰豆网上搜索。

作业实验13DOC.docx

作业实验13DOC

操作系统实验1~3理学院信息与计算科学1303许艳红学号2013310200724

 

实验1

1建立两个子进程

#include

main()

{

intchildpid1,childpid2;

while((childpid1=fork())==-1);

if(childpid1==0)

putchar('b');

else

{

while((childpid2=fork())==-1);

if(childpid2==0)

putchar('c');

else

putchar('a');

}

}

运行结果acb,bca,bac等,因为fork()创建进程的时间多于输出一个字符的时间,所以当创建进程2时,进程1一输出‘b',又进程2和主程序输出字符的次序具有随机性,所以会出现多种情况。

2.输出一句话

#include

intmain()

{

intpid;

pid=fork();

if(pid==0)

printf("Iamson,mypidis%d.\n",getpid());

elseif(pid>0)

{

printf("I'mfather,mypidis%d.\n",getpid());

pid=fork();

if(pid==0)

printf("I'mdaughterprocess,mypidis%d.\n",getpid());

elseif(pid>0)

printf("I'mfatherprocess,mypidis%d.\n",getpid());

else

printf("fork()error.\n");

}

elseprintf("fork()error.\n");

}

因为输出函数printf()输出字符时不会中断,所以输出的每句话就相当于一个字符,最终也会有多种情况。

进程加锁

#include

intmain()

{

intpid;

pid=fork();

if(pid==0)

printf("Iamson,mypidis%d.\n",getpid());

lockf(1,0,0);

elseif(pid>0)

{

/*从子进程1返回到父进程时,再创建子进程2。

*/

printf("I'mfather,mypidis%d.\n",getpid());

pid=fork();

if(pid==0)

lockf(1,0,0);

printf("I'mdaughterprocess,mypidis%d.\n",getpid());

elseif(pid>0)

lockf(1,0,0);

printf("I'mfatherprocess,mypidis%d.\n",getpid());

else

printf("fork()error.\n");

}

elseprintf("fork()error.\n");

}

与未上锁时输出的结果大致相同,这是因为不同进程之间不存在共享临界资源(其中打印机的互斥性已由操作系统保证)问题,所以加锁与不加锁效果相同。

3.软中断通信

#include

#include

#include

#include

#include

#include

#include

#include

voidgo();

voidstop1(),stop2();

pid_tp1,p2;

voidmain()

{

intstatus=-1;

intrtv;

while((p1=fork())==-1);/*创建子进程p1*/

if(p1>0)

{

while((p2=fork())==-1);/*创建子进程p2*/

if(p2>0)

{

printf("Parentprocess%d\n",getpid());

signal(SIGINT,go);/*接收到信号,转go*/

pause();

sleep

(2);

wait(NULL);

wait(NULL);

printf("Parentprocessiskilled!

\n");

exit(0);

}

else

{

printf("Process2,pid%d\n",getpid());

signal(SIGINT,SIG_IGN);

pre">signal(SIGUSR2,stop2);

if(signal(SIGUSR2,stop2)==SIG_ERR){

printf("Can'tcatchSIGUR2");

}

pause();

printf("Process2End\n");

}

}

else

{

printf("Process1,pid%d\n",getpid());

signal(SIGINT,SIG_IGN);

pre">

-webkit-auto;"if(signal(SIGUSR1,stop1)==SIG_ERR){

printf("Can'tcatchSIGUR2");

}

pause();

printf("Process1End\n");

}

printf("childexitstatusis%d\n",WEXITSTATUS(status));

}

voidgo()

{

intrtv;

printf("Funcgo\n");

rtv=kill(p1,SIGUSR1);/*向p1发软中断信号16*/

if(rtv){

printf("failtosendsignal16top1\n");

}else{

printf("Succedinsendingsignal16top1\n");

}

rtv=kill(p2,SIGUSR2);/*向p2发软中断信号17*/

if(rtv){

printf("failtosendsignal17top2\n");

}else{

printf("Succedinsendingsignal17top2\n");

}

}

voidstop2()

{

printf("Childprocess2iskilledbyparent!

\n");

exit(0);

}

voidstop1()

{

printf("Childprocess1iskilledbyparent!

\n");

exit(0);

}

Wait(0)用来实现父子进程的同步;因为进程从父进程中继承了Del信号,及其默认的处理程序,在子进程中并没有屏蔽Del信号,因此,当输入信号时,子进程会处理父进程为其指定的信号之前,调用默认的处理Del信号的程序,直接退出。

所以应该在子进程中屏蔽掉系统默认的对Del信号的处理

4进程的管道通信

#include

#include

#include

#include"stdlib.h"

intpid1,pid2;

main()

{

intfd[2];

charoutpipe[100],inpipe[100];

pipe(fd);

while((pid1=fork())==-1);

if(pid1==0)

{

printf("p1\n");

lockf(fd[1],1,0);

sprintf(outpipe,"child1processissendingmessage!

");

write(fd[1],outpipe,50);

sleep(5);

lockf(fd[1],0,0);

exit(0);

}

else

{

while((pid2=fork())==-1);

if(pid2==0)

{

lockf(fd[1],1,0);

sprintf(outpipe,"child2processissendingmessage!

");

write(fd[1],outpipe,50);

sleep(5);

lockf(fd[1],0,0);

exit(0);

}

else

{

wait(0);

read(fd[0],inpipe,50);

printf("%s\n",inpipe);

wait(0);

read(fd[0],inpipe,50);

printf("%s\n",inpipe);

exit(0);

}

}

}

管道通过lockf(),而lockf(fd[1],1,0)实现进程间的互斥,用write()写入管道,用read()读取管道内容,通过延迟一段时间,sleep(),子进程完成写入人物,由于管道中的延迟问题,否则在未完成写人物时,父进程调用读任务则出错

实验2

1消息的接受和发送

server建立一个key为75的消息队列,等待其它进程发来的消息。

当遇到类型为1的消息,则作为结束信号,取消该队列,并退出server。

server每接收到一个消息后显示一句“(server)received”。

client使用key为75的消息队列,先后发送类型从10到1的消息,然后退出。

最后一个消息,即是server端需要的结束信号。

client每发送一条消息后显示一句“(client)sent”

server.c参考程序如下:

#include

#include

#include

#include

#include

#defineMSGKEY75

structmsgform

{

longmtype;

charmtext[1000];

}msg;

intmsgqid;

voidserver()

{

msgqid=msgget(MSGKEY,0777|IPC_CREAT);/*创建75#消息队列*/

do

{

msgrcv(msgqid,&msg,1030,0,0);/*接收消息*/

printf("(server)received\n");

}while(msg.mtype!

=1);

msgctl(msgqid,IPC_RMID,0);/*删除消息队列,归还资源*/

exit(0);

}

main()

{

server();

}

client.c参考程序如下:

#include

#include

#include

#include

#include

#defineMSGKEY75

structmsgform

{

longmtype;

charmtext[1000];

}msg;

intmsgqid;

voidclient()

{

inti;

msgqid=msgget(MSGKEY,0777);/*打开75#消息队列*/

for(i=10;i>=1;i--)

{

msg.mtype=i;

printf("(client)sent\n");

msgsnd(msgqid,&msg,1024,0);/*发送消息*/

}

exit(0);

}

main()

{

client();

}

message的传送和控制并不能保证完全同步,当一个程序不在激活状态的时候,它完全可能继续睡眠,造成了上面的现象,在多次发送消息后才接收消息。

2.共享存储区的创建、附接和断接

#include

#include

#include

#defineSHMKEY75

intshmid,i,p1,p2;

int*addr;

voidCLIENT()/*发送过程*/

{

 inti;

 shmid=shmget(SHMKEY,1024,0777);/*打开共享存储区*/

 addr=(int*)shmat(shmid,0,0);/*获取共享存储区的首地址*/

 for(i=29;i>=0;i--)

 {

   while(*addr!

=-1);/*判断是否可写*/

   *addr=i;/*写数据*/

   printf("%d",*addr);

   printf("(client)sent\n");

 }

 exit(0);

}

voidSERVER()/*接收进程*/

{

 inti;

shmid=shmget(SHMKEY,1024,0777|IPC_CREAT);/*创建共享存储区*/

 addr=(int*)shmat(shmid,0,0);

 do

 {

  *addr=-1;

  while(*addr==-1);/*判断信息是否传来*/

  printf("%d",*addr+30);/*读,并加工数据*/

  printf("(server)received\n");

 }while(*addr);

 shmctl(shmid,IPC_RMID,0);/*撤消共享存储区,归还资源*/

 exit(0);

}

main()

{

 while((p1=fork())==-1);/*父进程*/

 if(p1==0)SERVER();/*子进程p1*/

 while((p2=fork())==-1);/*父进程*/

 if(p2==0)CLIENT();/*子进程p2*/

 wait(0);/*父进程*/

 wait(0);/*父进程*/

}

用主程序作为“引子”,先后fork()两个子进程,SERVER和CLIENT,让它们利用共享存储区的方式进行通信:

CLIENT端获取一个KEY为75的共享区,当共享区第一个字节的值为-1时,表示SERVER端空闲。

这时CLIENT向共享区中填入要发送的数据,同时显示自己发送的数据,然后显示一句“(client)sent”。

SERVER端获取(如果还没有就创建)一个KEY为75的共享存储区,并将第一个字节置为-1,作为数据空的标志,等待其他进程发来的消息。

当该字节的值发生变化时,表示收到了信息,SERVER取得该数据,进行处理,然后将处理结果显示出来,再显示一句“(server)received”。

发送和接收的过程循环进行30次。

父进程在SERVER和CLIENT均退出后结束。

 

实验三

#include

#include

#include

#defineTRUE1

#defineFALSE0

#defineINVALID-1

#defineNULL0

#definetotal_instruction320/*指令流长*/

#definetotal_vp32/*虚页长*/

#defineclear_period50/*清零周期*/

typedefstruct{/*页面结构*/

intpn,pfn,counter,time;

}pl_type;

pl_typepl[total_vp];/*页面结构数组*/

structpfc_struct{/*页面控制结构*/

intpn,pfn;

structpfc_struct*next;

};

structpfc_structpfc[total_vp],*freepf_head,*busypf_head,*busypf_tail;

intdiseffect,a[total_instruction];

intpage[total_instruction],offset[total_instruction];

voidinitialize();

voidFIFO();

voidLRU();

voidOPT();

voidLFU();

voidCLOCK();

voidNRU();

intmain()

{

intS,i;

srand(10*getpid());

S=(int)(319.0*rand()/RAND_MAX)+1;

for(i=0;i

a[i]=S;a[i+1]=a[i]+1;

a[i+2]=(int)(1.0*a[i]*rand()/RAND_MAX);a[i+3]=a[i+2]+1;S=(int)(1.0*rand()*(318-a[i+2])/RAND_MAX)+a[i+2]+2;

}

for(i=0;i

page[i]=a[i]/10;

offset[i]=a[i]%10;

}

for(i=4;i<=32;i++){

printf("%2dpageframes\t",i);

FIFO(i);

LRU(i);

NRU(i);

OPT(i);

SCR(i);

CLOCK(i);

}

return0;

}

voidinitialize(inttotal_pf)

{

inti;

diseffect=0;

for(i=0;i

{

pl[i].pn=i;

pl[i].pfn=INVALID;pl[i].counter=0;

pl[i].time=-1;}

for(i=1;i

{

pfc[i-1].next=&pfc[i];

pfc[i-1].pfn=i-1;

}

pfc[total_pf-1].next=NULL;

pfc[total_pf-1].pfn=total_pf-1;

freepf_head=&pfc[0];

}

voidFIFO(inttotal_pf)

{

inti;

structpfc_struct*p;

initialize(total_pf);

busypf_head=busypf_tail=NULL;

for(i=0;i

{

if(pl[page[i]].pfn==INVALID){

diseffect+=1;

if(freepf_head==NULL)

{

p=busypf_head->next;

pl[busypf_head->pn].pfn=INVALID;

freepf_head=busypf_head;

freepf_head->next=NULL;

busypf_head=p;

}

p=freepf_head->next;,

freepf_head->next=NULL;

freepf_head->pn=page[i];

pl[page[i]].pfn=freepf_head->pfn;

if(busypf_tail==NULL)busypf_head=busypf_tail=freepf_head;

else

{

busypf_tail->next=freepf_head;

busypf_tail=freepf_head;

}

freepf_head=p;

}

}

printf("FIFO:

%6.4f",1-(float)diseffect/320);

}

我在这里只定义了initialize()函数和FIFO()算法,因为只充分了解FIFO()算法,即顺序写入数据,顺序读出数据,是一种先进先出的数据缓存。

又了解到虚拟存储器的优缺点,即不用存储器,直接调出来就好,但其容量太小。

与其他算法相比,这种算法的命中率最低。

另外,随机数的产生可以用函数srand(),rand()

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 教学研究 > 教学计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1