当前位置:文档之家› 操作系统实验答案

操作系统实验答案

操作系统实验答案
操作系统实验答案

部分实验答案

第三部分操作系统实验指导

实验3 指导

[实验内容]

1.进程的创建

〈任务〉

编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符;父进程显示字符“a”,子进程分别显示字符“b”和“c”。试观察记录屏幕上的显示结果,并分析原因。

〈程序〉

#include

main()

{

int p1,p2;

if(p1=fork()) /*子进程创建成功*/

putchar('b');

else

{

if(p2=fork()) /*子进程创建成功*/

putchar('c');

else putchar('a'); /*父进程执行*/

}

}

<运行结果>

bca(有时会出现abc的任意的排列)

分析:从进程执行并发来看,输出abc的排列都是有可能的。

原因:fork()创建进程所需的时间虽然可能多于输出一个字符的时间,但各个进程的时间片的获得却不是一定是顺序的,所以输出abc的排列都是有可能的。

2.进程的控制

<任务>

修改已编写好的程序,将每个程序的输出由单个字符改为一句话,再观察程序执行时屏幕上出现的现象,并分析其原因。如果在程序中使用系统调用lockf()来给每个程序加锁,可以实现进程之间的互斥,观察并分析出现的现象。

〈程序1〉

#include

main()

{

int p1,p2,i;

if(p1=fork())

{

for(i=0;i<500;i++)

printf("parent%d\n",i);

wait(0); /* 保证在子进程终止前,父进程不会终止*/

exit(0);

}

else

{

if(p2=fork())

{

for(i=0;i<500;i++)

printf("son %d\n",i);

wait(0); /* 保证在子进程终止前,父进程不会终止*/

exit(0); /*向父进程信号0且该进程推出*/

}

else

{

for(i=0;i<500;i++)

printf(“grandchild %d\n",i);

exit(0);

}

}

}

〈运行结果〉

parent….

son…

grandchild…

grandchild…

或grandchild

…son

…grandchild

…son

…parent

分析:由于函数printf()输出的字符串之间不会被中断,因此,每个字符串内部的字符顺序输出时不变。但是 , 由于进程并发执行时的调度顺序和父子进程的抢占处理机问题,输出字符串的顺序和先后随着执行的不同而发生变化。这与打印单字符的结果相同。

〈程序2〉

#include

main()

{

int p1,p2,i;

if(p1=fork())

{

lockf(1,1,0);

for(i=0;i<500;i++)

printf("parent %d\n",i);

lockf(1,0,0);

wait(0); /* 保证在子进程终止前,父进程不会终止*/

exit(0);

}

else

{

if(p2=fork())

{

lockf(1,1,0);

for(i=0;i<500;i++)

printf("son %d\n",i);

lockf(1,0,0);

wait(0); /* 保证在子进程终止前,父进程不会终止*/

exit(0);

}

else

{

lockf(1,1,0);

for(i=0;i<500;i++)

printf("daughter %d\n",i);

lockf(1,0,0);

exit(0);

}

}

}

<运行结果〉

输出parent块,son块,grandchild块的顺序可能不同,但是每个块的输出过程不会被打断。

分析:因为上述程序执行时,lockf(1,1,0)锁定标准输出设备,lockf(1,0,0)解锁标准输出设备,在lockf(1,1,0)与lockf(1,0,0)中间的for循环输出不会被中断,加锁与不加锁效果不相同。

3.软中断通信

〈任务1〉

编制一段程序,使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按ctrl+c键),当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止:

child process1 is killed by parent!

child process2 is killed by parent!

父进程等待两个子进程终止后,输出以下信息后终止:

parent process is killed!

<程序流程图>

〈程序〉

#include

#include

#include

void waiting(),stop(),alarming(); int wait_mark;

main()

{

int p1,p2;

if(p1=fork()) /*创建子进程p1*/

{

if(p2=fork()) /*创建子进程p2*/

{

wait_mark=1;

signal(SIGINT,stop); /*接收到^c信号,转stop*/

signal(SIGALRM,alarming);/*接受SIGALRM

waiting();

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

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

wait(0); /*同步*/

wait(0);

printf("parent process is killed!\n");

exit(0);

}

else

{

wait_mark=1;

signal(17,stop);

signal(SIGINT,SIG_IGN); /*忽略^c信号*/

while (wait_mark!=0);

lockf(1,1,0);

printf("child process2 is killed by parent!\n");

lockf(1,0,0);

exit(0);

}

}

else

{

wait_mark=1;

signal(16,stop);

signal(SIGINT,SIG_IGN); /*忽略^c信号*/

while (wait_mark!=0)

lockf(1,1,0);

printf("child process1 is killed by parent!\n");

lockf(1,0,0);

exit(0);

}

}

void waiting()

{

sleep(5);

if (wait_mark!=0)

kill(getpid(),SIGALRM);

}

void alarming()

{

wait_mark=0;

}

void stop()

{

wait_mark=0;

}

<运行结果>

不做任何操作等待五秒钟父进程回在子进程县推出后退出,并打印退出的顺序;或者点击ctrl+C后程序退出并打印退出的顺序。

〈任务2〉

在上面的任务1中,增加语句signal(SIGINT,SIG_IGN)和语句signal(SIGQUIT,SIG_IGN),观察执行结果,并分析原因。这里,signal(SIGINT,SIG_IGN)和signal(SIGQUIT,SIG_IGN)分别为忽略键信号以及忽略中断信号。

<程序>

#include

#include

#include

int pid1,pid2;

int EndFlag=0;

int pf1=0;

int pf2=0;

void IntDelete()

{

kill(pid1,16);

kill(pid2,17);

}

void Int1()

{

printf("child process 1 is killed !by parent\n");

exit(0);

}

void Int2()

{

printf("child process 2 is killed !by parent\n");

exit(0);

}

main()

{

int exitpid;

if(pid1=fork())

{

if(pid2=fork())

{

signal(SIGINT,IntDelete);

waitpid(-1,&exitpid,0);

waitpid(-1,&exitpid,0);

printf("parent process is killed\n");

exit(0);

}

else

{

signal(SIGINT,SIG_IGN);

signal(17,Int2);

pause();

}

}

else

{

signal(SIGINT,SIG_IGN);

signal(16,Int1);

pause();

}

}

〈运行结果〉

请读者将上述程序输入计算机后,执行并观察。

3.进程的管道通信

〈任务〉

编制一段程序,实现进程的管道通信。使用系统调用pipe()建立一条管道线。两个子进程p1和p2分别向通道个写一句话:

child1 process is sending message!

child2 process is sending message!

而父进程则从管道中读出来自两个进程的信息,显示在屏幕上。

〈程序〉

#include

#include

#include

int pid1,pid2;

main( )

{

int fd[2];

char outpipe[100],inpipe[100];

pipe(fd); /*创建一个管道*/

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

if(pid1==0)

{

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

sprintf(outpipe,"child 1 process is sending message!");

/*把串放入数组outpipe中*/

write(fd[1],outpipe,50); /*向管道写长为50字节的串*/

sleep(5); /*自我阻塞5秒*/

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

exit(0);

}

else

{

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

if(pid2==0)

{

lockf(fd[1],1,0); /*互斥*/

sprintf(outpipe,"child 2 process is sending message!");

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

sleep(5);

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

exit(0);

}

else

{

wait(0); /*同步*/

read(fd[0],inpipe,50); /*从管道中读长为50字节的串*/

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

wait(0);

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

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

exit(0);

}

}

}

〈运行结果〉

延迟5秒后显示:

child1 process is sending message!

再延迟5秒:

child2 process is sending message!

〈分析〉

请读者自行完成。

<思考>

1、程序中的sleep(5)起什么作用?

2、子进程1和2为什么也能对管道进行操作?

实验4指导

[实验内容]

1 消息的创建,发送和接收

〈任务〉

使用系统调用msgget( ), megsnd( ), msgrev( )及msgctl()编制一长度为1K的消息发送和接收的程序。

〈程序设计〉

(1)为了便于操作和观察结果,用一个程序为“引子”,先后fork( )两个子进程,SERVER和CLIENT,进行通信。

(2)SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER 。SERVER每接收到一个消息后显示一句“(server)received”。

(3)CLIENT端使用Key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后的一个消息,既是 SERVER端需要的结束信号。CLIENT每发送一条消息后显示一句“(client)sent”。(4)父进程在 SERVER和 CLIENT均退出后结束。

〈程序〉

#include

#include

#include

#include

#define MSGKEY 75 /*定义关键词MEGKEY*/

struct msgform /*消息结构*/

{

long mtype;

char mtexe[100]; /*文本长度*/

}msg;

int msgqid,i;

void CLIENT( )

{

int i;

msgqid=msgget(MSGKEY,0777|IPC_CREAT);

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

{

msg.mtype=i;

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

msgsnd(msgqid,&msg,1030,0); /*发送消息msg入msgid消息队列*/

}

exit(0);

}

void SERVER( )

{

msgqid=msgget(MSGKEY,0777|IPC_CREAT); /*由关键字获得消息队列*/

do

{

msgrcv(msgqid,&msg,1030,0,0); /*从队列msgid接受消息msg*/

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

}while(msg.mtype!=1); /*消息类型为1时,释放队列*/

msgctl(msgqid, IPC_RMID,0);

}

main()

{

if(fork())

{

SERVER();

wait(0);

}

else CLIENT( );

}

<结果>

从理想的结果来说,应当是每当Client发送一个消息后,server接收该消息,Client再发送下一条。

也就是说“(Client)sent”和“(server)received”的字样应该在屏幕上交替出现。实际的结果大多是,

先由 Client 发送两条消息,然后Server接收一条消息。此后Client

Server交替发送和接收消息.最后一次接收两条消息. Client 和Server 分别发送和接收了10条消息,

与预期设想一致

<分析>

message的传送和控制并不保证完全同步,当一个程序不再激活状态的时候,它完全可能继续睡眠,造

成上面现象,在多次send message 后才 receive message.这一点有助于理解消息转送的实现机理.

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

<任务>

使用系统调用shmget(),sgmat(),smgdt(),shmctl()编制一个与上述功能相同的程序.

<程序设计>

(1)为了便于操作和观察结果,用一个程序为“引子”,先后fork( )两个子进程,SERVER

和 CLIENT,进行通信。

(2)SERVER端建立一个KEY为75的共享区,并将第一个字节置为-1.作为数据空的标志.等待其他进程发来的消息.当该字节的值发生变化时,表示收到了该消息,进行处理.然后再次把它的值设为-1.如果遇到的值为0,则视为结束信号,取消该队列,并退出SERVER.SERVER每接收到一次数据后显示”(server)received”.

(3)CLIENT端建立一个为75的共享区,当共享取得第一个字节为-1时, Server端空闲,可发送请求. CLIENT 随即填入9到0.期间等待Server端再次空闲.进行完这些操作后, CLIENT 退出. CLIENT每发送一次数据后显示”(client)sent”.

(4)父进程在SERVER和CLIENT均退出后结束.

<程序>

#include

#include

#include

#define SHMKEY 75 /*定义共享区关键词*/

int shmid,i;

int *addr;

CLIENT()

{

int i;

shmid=shmget(SHMKEY,1024, 0777|IPC_CREAT); /*获取共享区,长度1024,关键词SHMKEY*/ addr=shmat(shmid,0,0); /*共享区起始地址为addr*/

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

{

while(*addr!= -1);

printf("(client)sent\n"); /*打印(client)sent*/

*addr=i; /*把i赋给addr*/

}

exit(0);

}

SERVER()

{

do

{

while(*addr = =-1);

printf("(server)received\n%d",*addr); /*服务进程使用共享区*/

if(*addr!=0)

*addr=-1;

} while(*addr);

wait(0);

shmctl(shmid,IPC_RMID,0);

}

main()

{

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

addr=shmat(shmid,0,0); /*共享区起始地址为addr*/

*addr=-1;

if(fork())

{

SERVER();

}

else

{

CLIENT();

}

}

<结果〉

运行的结果和预想的完全一样。但在运行的过程中,发现每当client发送一次数据后,server要等大约0.1秒才有响应。同样,之后client又需要等待大约0.1秒才发送下一个数据。

<分析〉

出现上述的应答延迟的现象是程序设计的问题。当client端发送了数据后,并没有任何措施通知server端数据已经发出,需要由client的查询才能感知。此时,client端并没有放弃系统的控制权,仍然占用CPU的时间片。只有当系统进行调度时,切换到了server进程,再进行应答。这个问题,也同样存在于server端到client的应答过程之中。

3 比较两种消息通信机制中的数据传输的时间

由于两种机制实现的机理和用处都不一样,难以直接进行时间上的比较。如果比较其性能,应更加全面的分析。

(1)消息队列的建立比共享区的设立消耗的资源少.前者只是一个软件上设定的问题,后者需要对硬件

操作,实现内存的映像,当然控制起来比前者复杂.如果每次都重新进行队列或共享的建立,共享区的设立没有什么优势。

(2)当消息队列和共享区建立好后,共享区的数据传输,受到了系统硬件的支持,不耗费多余的资源;而

消息传递,由软件进行控制和实现,需要消耗一定的CPU资源.从这个意义上讲,共享区更适合频繁和大量的数据传输.

(3)消息的传递,自身就带有同步的控制.当等到消息的时候,进程进入睡眠状态,不再消耗CPU资源.而

共享队列如果不借助其他机制进行同步,接受数据的一方必须进行不断的查询,白白浪费了大量的CPU资源.可见消息方式的使用更加灵活.

实验5指导

[实验内容]

<任务>

设计一个虚拟存储区和内存工作区,并使用下列算法计算访问命中率.

(1)进先出的算法(FIFO)

(2)最近最少使用的算法(LRU)

(3)最佳淘汰算法(OPT)

(4)最少访问页面算法(LFU)

(5)最近最不经常使用算法(NUR)

命中率=(1-页面失效次数)/页地址流长度

<程序设计〉

本实验的程序设计基本上按照实验内容进行。即首先用srand()和rand()函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。相关定义如下:

1 数据结构

(1)页面类型

typedef struct{

int pn,pfn,counter,time;

}pl-type;

其中pn 为页号,pfn为面号, counter为一个周期内访问该页面的次数, time为访问时间.

(2) 页面控制结构

pfc-struct{

int pn,pfn;

struct pfc_struct *next;

}

typedef struct pfc_struct pfc_type;

pfc_type pfc_struct[total_vp],*freepf_head,*busypf_head;

pfc_type *busypf_tail;

其中pfc[total_vp]定义用户进程虚页控制结构,

*freepf_head为空页面头的指针,

*busypf_head为忙页面头的指针,

*busypf_tail为忙页面尾的指针.

2.函数定义

(1)Void initialize( ):初始化函数,给每个相关的页面赋值.

(2)Void FIFO( ):计算使用FIFO算法时的命中率.

(3)Void LRU( ):计算使用LRU算法时的命中率.

(4)Void OPT( ):计算使用OPT算法时的命中率.

(5)Void LFU( ):计算使用LFU算法时的命中率.

(6)Void NUR( ):计算使用NUR算法时的命中率.

3.变量定义

(1)int a[total_instruction]: 指令流数据组.

(2)int page[total_instruction]: 每条指令所属的页号.

(3)int offset[total_instruction]: 每页装入10条指令后取模运算页号偏移值.

(4)int total_pf: 用户进程的内存页面数.

(5)int disaffect: 页面失效次数.

4.程序参考源码及结果

<程序>

#define TRUE 1

#define FALSE 0

#define INVALID -1

#define NULL 0

#define total_instruction 320 /*指令流长*/

#define total_vp 32 /*虚页长*/

#define clear_period 50 /*清0周期*/

typedef struct /*页面结构*/

{

int pn; //页号 logic number

int pfn; //页面框架号 physical frame number

int counter; //计数器

int time; //时间

}pl_type;

pl_type pl[total_vp]; /*页面线性结构---指令序列需要使用地址*/

typedef struct pfc_struct /*页面控制结构,调度算法的控制结构*/

{

int pn;

int pfn;

struct pfc_struct *next;

}pfc_type;

pfc_type pfc[total_vp], *freepf_head, *busypf_head, *busypf_tail;

int diseffect, a[total_instruction]; /* a[]为指令序列*/

int page[total_instruction], offset[total_instruction];/*地址信息*/

int initialize(int);

int FIFO(int);

int LRU(int);

int LFU(int);

int NUR(int); //not use recently

int OPT(int);

int main( )

{

int s,i,j;

srand(10*getpid()); /*由于每次运行时进程号不同,故可用来作为初始化随机数队列的“种子”*/

s=(float)319*rand( )/32767/32767/2+1; /*正态分布*/

for(i=0;i

{

if(s<0||s>319)

{

printf("When i==%d,Error,s==%d\n",i,s);

exit(0);

}

a[i]=s; /*任选一指令访问点m*/

a[i+1]=a[i]+1; /*顺序执行一条指令*/

a[i+2]=(float)a[i]*rand( )/32767/32767/2; /*执行前地址指令m*/

a[i+3]=a[i+2]+1; /*顺序执行一条指令*/

s=(float)(318-a[i+2])*rand( )/32767/32767/2+a[i+2]+2;

if((a[i+2]>318)||(s>319))

printf("a[%d+2],a number which is :%d and s==%d\n",i,a[i+2],s);

}

for (i=0;i

{

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

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

}

for(i=4;i<=32;i++) /*用户内存工作区从4个页面到32个页面*/

{

printf("---%2d page frames---\n",i);

FIFO(i);

LRU(i);

LFU(i);

NUR(i);

OPT(i);

}

return 0;

}

/*初始化相关数据结构 total_pf表示内存的块数 */

int initialize(int total_pf)

{

int i;

diseffect=0;

for(i=0;i

{

pl[i].pfn=INVALID; /*置页面控制结构中的页号,页面为空*/

pl[i].counter=0; /*页面控制结构中的访问次数为0*/

pl[i].time=-1; /*访问的时间*/

}

for(i=0;i

{

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

pfc[i].pfn=i;

}

pfc[total_pf-1].next=NULL;

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

freepf_head=&pfc[0]; /*空页面队列的头指针为pfc[0]*/

return 0;

}

int FIFO(int total_pf) /*先进先出算法total_pf:用户进程的内存页面数*/ {

int i,j;

pfc_type *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->pn=page[i];

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

freepf_head->next=NULL; /*使busy的尾为null*/

if(busypf_tail==NULL)

{

busypf_tail=busypf_head=freepf_head;

}

else

{

busypf_tail->next=freepf_head;

busypf_tail=freepf_head;

}

freepf_head=p;

}

}

printf("FIFO:%6.4f\n",1-(float)diseffect/320);

return 0;

int LRU (int total_pf) /*最近最久未使用算法least recently used*/

{

int min,minj,i,j,present_time; /*minj为最小值下标*/

initialize(total_pf);

present_time=0;

for(i=0;i

{

if(pl[page[i]].pfn==INVALID) /*页面失效*/

{

diseffect++;

if(freepf_head==NULL) /*无空闲页面*/

{

min=32767; /*设置最大值*/

for(j=0;j

{

if(min>pl[j].time&&pl[j].pfn!=INVALID)

{

min=pl[j].time;

minj=j;

}

}

freepf_head=&pfc[pl[minj].pfn]; //腾出一个单元

pl[minj].pfn=INVALID;

pl[minj].time=0;

freepf_head->next=NULL;

}

pl[page[i]].pfn=freepf_head->pfn; //有空闲页面,改为有效

pl[page[i]].time=present_time;

freepf_head=freepf_head->next; //减少一个free 页面

}

else

{

pl[page[i]].time=present_time; //命中则增加该单元的访问次数

present_time++;

}

}

printf("LRU:%6.4f\n",1-(float)diseffect/320);

return 0;

}

int NUR(int total_pf ) /*最近未使用算法Not Used recently count表示*/ {

int i,j,dp,cont_flag,old_dp;

pfc_type *t;

initialize(total_pf);

dp=0;

for(i=0;i

{

if (pl[page[i]].pfn==INVALID) /*页面失效*/

{

diseffect++;

if(freepf_head==NULL) /*无空闲页面*/

{

cont_flag=TRUE;

old_dp=dp;

while(cont_flag)

{

if(pl[dp].counter==0&&pl[dp].pfn!=INVALID)

cont_flag=FALSE;

else

{

dp++;

if(dp==total_vp)

dp=0;

if(dp==old_dp)

for(j=0;j

pl[j].counter=0;

}

}

freepf_head=&pfc[pl[dp].pfn];

pl[dp].pfn=INVALID;

freepf_head->next=NULL;

}

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

freepf_head->pn=page[i];

freepf_head=freepf_head->next;

}

else

pl[page[i]].counter=1;

if(i%clear_period==0)

for(j=0;j

pl[j].counter=0;

}

printf("NUR:%6.4f\n",1-(float)diseffect/320);

return 0;

}

int OPT(int total_pf) /*最佳置换算法*/

{

int i,j, max,maxpage,d,dist[total_vp];

pfc_type *t;

initialize(total_pf);

for(i=0;i

{

if(pl[page[i]].pfn==INVALID) /*页面失效*/

{

diseffect++;

if(freepf_head==NULL) /*无空闲页面*/

{

for(j=0;j

{

if(pl[j].pfn!=INVALID)

dist[j]=32767;

else

dist[j]=0;

}

for(j=0;j

{

if((pl[j].pfn!=INVALID)&&(dist[j]==32767))

{

dist[j]=j;

}

}

max=0;

for(j=0;j

if(max

{

max=dist[j];

maxpage=j;

}

freepf_head=&pfc[pl[maxpage].pfn];

freepf_head->next=NULL;

pl[maxpage].pfn=INVALID;

}

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

freepf_head=freepf_head->next;

}

}

printf("OPT:%6.4f\n",1-(float)diseffect/320);

return 0;

}

/*该算法时根据已知的预测未知的,least frequency Used是最不经常使用置换法*/ int LFU(int total_pf)

{

int i,j,min,minpage;

pfc_type *t;

initialize(total_pf);

for(i=0;i

{

if(pl[page[i]].pfn==INVALID) /*页面失效*/

{

diseffect++;

if(freepf_head==NULL) /*无空闲页面*/

{

min=32767;

/*获取counter的使用用频率最小的内存*/

for(j=0;j

{

if(min>pl[j].counter&&pl[j].pfn!=INVALID)

{

min=pl[j].counter;

minpage=j;

}

}

freepf_head=&pfc[pl[minpage].pfn];

pl[minpage].pfn=INVALID;

pl[minpage].counter=0;

freepf_head->next=NULL;

}

pl[page[i]].pfn=freepf_head->pfn; //有空闲页面,改为有效

pl[page[i]].counter++;

freepf_head=freepf_head->next; //减少一个free 页面}

else

{

pl[page[i]].counter;

pl[page[i]].counter=pl[page[i]].counter+1;

}

}

printf("LFU:%6.4f\n",1-(float)diseffect/320);

return 0;

}

<结果一:〉

4 page framesFIFO:0.2562LRU:0.2531OPT:0.3031LFU:0.2812NUR:0.2812

5 page framesFIFO:0.2969LRU:0.2906OPT:0.3500LFU:0.3219NUR:0.3094

6 page framesFIFO:0.3375LRU:0.3281OPT:0.3844LFU:0.3375NUR:0.3344

7 page framesFIFO:0.3563LRU:0.3563OPT:0.4031LFU:0.3563NUR:0.3500

嵌入式操作系统实验报告

中南大学信息科学与工程学院实验报告 姓名:安磊 班级:计科0901 学号: 0909090310

指导老师:宋虹

目录 课程设计内容 ----------------------------------- 3 uC/OS操作系统简介 ------------------------------------ 3 uC/OS操作系统的组成 ------------------------------ 3 uC/OS操作系统功能作用 ---------------------------- 4 uC/OS文件系统的建立 ---------------------------- 6 文件系统设计的原则 ------------------------------6 文件系统的层次结构和功能模块 ---------------------6 文件系统的详细设计 -------------------------------- 8 文件系统核心代码 --------------------------------- 9 课程设计感想 ------------------------------------- 11 附录-------------------------------------------------- 12

课程设计内容 在uC/OS操作系统中增加一个简单的文件系统。 要求如下: (1)熟悉并分析uc/os操作系统 (2)设计并实现一个简单的文件系统 (3)可以是存放在内存的虚拟文件系统,也可以是存放在磁盘的实际文件系统 (4)编写测试代码,测试对文件的相关操作:建立,读写等 课程设计目的 操作系统课程主要讲述的内容是多道操作系统的原理与技术,与其它计算机原理、编译原理、汇编语言、计算机网络、程序设计等专业课程关系十分密切。 本课程设计的目的综合应用学生所学知识,建立系统和完整的计算机系统概念,理解和巩固操作系统基本理论、原理和方法,掌握操作系统开发的基本技能。 I.uC/OS操作系统简介 μC/OS-II是一种可移植的,可植入ROM的,可裁剪的,抢占式的,实时多任务操作系统内核。它被广泛应用于微处理器、微控制器和数字信号处理器。 μC/OS 和μC/OS-II 是专门为计算机的嵌入式应用设计的,绝大部分代码是用C语言编写的。CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。用户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件工具,就可以将μC/OS-II嵌入到开发的产品中。μC/OS-II 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点,最小内核可编译至2KB 。μC/OS-II 已经移植到了几乎所有知名的CPU 上。 严格地说uC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。没有提供输入输出管理,文件系统,网络等额外的服务。但由于uC/OS-II良好的可扩展性和源码开放,这些非必须的功能完全 可以由用户自己根据需要分别实现。 uC/OS-II目标是实现一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供最基本的系统服务,如信号量,邮箱,消息队列,内存管理,中断管理等。 uC/OS操作系统的组成 μC/OS-II可以大致分成核心、任务处理、时间处理、任务同步与通信,CPU的移植等5个部分。如下图:

RTOS实时操作系统(Real Time Operating System)

John Lee 20:27:07 上次讲到了 RTOS 的抢占机制对事件响应能力提高的帮助,避免了事件的丢失。 John Lee 20:27:07 上次讲到了 RTOS 的抢占机制对事件响应能力提高的帮助,避免了事件的丢失。小道(569198569) 20:27:39 老师辛苦 John Lee 20:27:45 但光依靠 RTOS 的抢占机制,并不能做到完全不丢失事件,只是从一定程度上降低了丢失事件的机率。 丶砖家(1361439207) 20:28:16 LEE 丶砖家(1361439207) 20:28:14 好复杂呀 John Lee 20:28:54 上次的这个图: John Lee 20:30:20 是没有丢失事件了,但如果我们把 E2 的第 3 个事件提前一些: John Lee 20:32:30 对于这样情况,RTOS 提供了一些带有通信功能的同步对象,可以让应用程序构造软件缓冲机制,来保持突发事件。 John Lee 20:33:19 关于具体的实现方法,要等到我们学习完了 RTOS 同步机制和各种同步对象后,才能讨论。

John Lee 20:34:24 除此之外,还有其它一些系统设计时,需要仔细考虑的问题: 中断处理时间到底多长合适? 等待设备事件产生,是否一定要用中断? 如何划分任务? 如何确定合适的调度算法? 是否需要任务优先级? 静态优先级能不能满足要求? 系统节拍的频率多少合适? 如何选则合适的同步对象? DsPower小灰灰(108430786) 20:35:56 对这就是我的问题 wei(34103820) 20:36:02 John Lee 20:36:07 这些问题,都留到我们学习完 RTOS 后,再来讨论。 小道(569198569) 20:36:23 wei(34103820) 20:36:02 遵守纪律 John Lee 20:36:39 现在讨论,很多同学没有基础,晕的。 John Lee 20:37:12 我们继续学习《嵌入式系统的实时概念》。 DsPower小灰灰(108430786) 20:38:13 支持老师 DsPower小灰灰(108430786) 20:38:14 雪狼(982332664) 20:38:55 我都晕乎了 John Lee 20:40:01 我们上次停下来的地方,是: 4.4.5 调度算法。

管理信息系统实验及答案(1)复习进程

第一章学校教务管理信息系统项目规划 一、开发背景介绍 信息社会的高科技,商品经济化的高效益,使计算机的应用已普及到经济和社会生活的各个领域。这对于正在迅速发展的各大高校而言,同样有着重要意义。现如今高校为适应社会的需求以及自身办学的需要,扩建、扩招已在寻常不过。自然就会有更多的学生信息需要处理。如果只靠人力来完成,必然是一项非常繁琐、复杂的工作,而且还会出现很多意想不到的错误,这不仅会给教学及管理带来了很大的不便,也不益于学校全面快速发展的需要。在高校中,教务管理工作具有举足轻重的地位,教学质量直接取决十教务管理水平。现如今教务管理信息系统的开发与实施可谓日新月异。在数字校园理论逐步应用的过程中,各高校一方面不断投资购建各种硬件、系统软件和网络,另一方面也不断开发实施了各类教学、科研、办公管理等应用系统,形成了一定规模的信息化建设体系。教务管理系统是一个庞大而复杂的系统,它包括对学生信息的注册、修改,学生选课及课程管理和学生的四六级考试及计算机等级考试的管理;对教师课程的管理以及对选课学生评分的管理;和管理员对教师、各类考试的综合管理等主要的功能。教务管理系统运行的状况将直接影响到学校里的主要工作,一旦此系统出错,不仅学校的教学进度安排会受到一定程度的影响,而且还会危及到每一个在校学生的切身利益。所以设计一个功能相对完整、操作简单以及界面友好的教务管理系统变得非常重要。为了提高教务管理的工作效率和服务质量,降低出错率,精简人力、物力的投入,各个高校均建立了自己的教务管理信息系统,为学校的动态管理和分析决策带来了极大的便利。现在的学校的教务管理也逐步从手工转到计算机自动化信息处理阶段。通过这个系统,用户可以方便的对教师信息以及学生信息和学生成绩资料进行添加、修改和删除操作,还可以对学生资料和成绩进行查询操作。除此之外,对用户的添加和删除操作也很方便。教务管理系统是典型的信息管理系统(MIS),它能够实现整体规划教学资源(学生,教师,教室),评估教学质量,制定教学计划,检查教学进度,给学校的教务人员管理教务工作提供了极大的方便。

实时操作系统报告

实时操作系统课程实验报告 专业:通信1001 学号:3100601025 姓名:陈治州 完成时间:2013年6月11日

实验简易电饭煲的模拟 一.实验目的: 掌握在基于嵌入式实时操作系统μC/OS-II的应用中,基于多任务的模式的编程方法。锻炼综合应用多任务机制,任务间的通信机制,内存管理等的能力。 二.实验要求: 1.按“S”开机,系统进入待机状态,时间区域显示当前北京时间,默认模式“煮饭”; 2.按“C”选择模式,即在“煮饭”、“煮粥”和“煮面”模式中循环选择; 3.按“B”开始执行模式命令,“开始”状态选中,时间区域开始倒计时,倒计时完成后进入“保温”状态,同时该状态显示选中,时间区域显示保温时间; 4.按“Q”取消当前工作状态,系统进入待机状态,时间区域显示北京时间,模式为当前模式; 5.按“X”退出系统,时间区域不显示。 6.煮饭时长为30,煮粥时长为50,煮面时长为40. 三.实验设计: 1.设计思路: 以老师所给的五个程序为基础,看懂每个实验之后,对borlandc的操作有了大概的认识,重点以第五个实验Task_EX为框架,利用其中界面显示与按键扫描以及做出相应的响应,对应实现此次实验所需要的功能。 本次实验分为界面显示、按键查询与响应、切换功能、时钟显示与倒计时模块,综合在一起实验所需功能。 2.模块划分图: (1)界面显示: Main() Taskstart() Taskstartdispinit() 在TaskStartDispInit()函数中,使用PC_DispStr()函数画出界面。

(2)按键查询与响应: Main() Taskstart() 在TaskStart()函数中,用if (PC_GetKey(&key) == TRUE)判断是否有按键输入。然后根据key 的值,判断输入的按键是哪一个;在响应中用switch语句来执行对应按键的响应。 (3)切换功能: l计数“C”按 键的次数 M=l%3 Switch(m) M=0,1,2对应于煮饭,煮粥,煮面,然后使用PC_DispStr()函数在选择的选项前画上“@”指示,同时,在其余两项钱画上“”以“擦出”之前画下的“@”,注意l自增。 四.主要代码: #include "stdio.h" #include "includes.h" #include "time.h" #include "dos.h" #include "sys/types.h" #include "stdlib.h" #define TASK_STK_SIZE 512 #define N_TASKS 2 OS_STK TaskStk[N_TASKS][TASK_STK_SIZE]; OS_STK TaskStartStk[TASK_STK_SIZE]; INT8U TaskData[N_TASKS];

操作系统原理-进程调度实验报告

一、实验目的 通过对进程调度算法的设计,深入理解进程调度的原理。 进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。 进程调度分配处理机,是控制协调进程对CPU的竞争,即按一定的调度算法从就绪队列中选中一个进程,把CPU的使用权交给被选中的进程。 进程通过定义一个进程控制块的数据结构(PCB)来表示;每个进程需要赋予进程ID、进程到达时间、进程需要运行的总时间的属性;在RR中,以1为时间片单位;运行时,输入若干个进程序列,按照时间片输出其执行序列。 二、实验环境 VC++6.0 三、实验内容 实现短进程优先调度算法(SPF)和时间片轮转调度算法(RR) [提示]: (1) 先来先服务(FCFS)调度算法 原理:每次调度是从就绪队列中,选择一个最先进入就绪队列的进程,把处理器分配给该进程,使之得到执行。该进程一旦占有了处理器,它就一直运行下去,直到该进程完成或因发生事件而阻塞,才退出处理器。 将用户作业和就绪进程按提交顺序或变为就绪状态的先后排成队列,并按照先来先服务的方式进行调度处理,是一种最普遍和最简单的方法。它优先考虑在系统中等待时间最长的作业,而不管要求运行时间的长短。 按照就绪进程进入就绪队列的先后次序进行调度,简单易实现,利于长进程,CPU繁忙型作业,不利于短进程,排队时间相对过长。 (2) 时间片轮转调度算法RR

原理:时间片轮转法主要用于进程调度。采用此算法的系统,其程序就绪队列往往按进程到达的时间来排序。进程调度按一定时间片(q)轮番运行各个进程. 进程按到达时间在就绪队列中排队,调度程序每次把CPU分配给就绪队列首进程使用一个时间片,运行完一个时间片释放CPU,排到就绪队列末尾参加下一轮调度,CPU分配给就绪队列的首进程。 固定时间片轮转法: 1 所有就绪进程按 FCFS 规则排队。 2 处理机总是分配给就绪队列的队首进程。 3 如果运行的进程用完时间片,则系统就把该进程送回就绪队列的队尾,重新排队。 4 因等待某事件而阻塞的进程送到阻塞队列。 5 系统把被唤醒的进程送到就绪队列的队尾。 可变时间片轮转法: 1 进程状态的转换方法同固定时间片轮转法。 2 响应时间固定,时间片的长短依据进程数量的多少由T = N × ( q + t )给出的关系调整。 3 根据进程优先级的高低进一步调整时间片,优先级越高的进程,分配的时间片越长。 多就绪队列轮转法: (3) 算法类型 (4)模拟程序可由两部分组成,先来先服务(FCFS)调度算法,时间片轮转。流程图如下:

操作系统实验报告一

重庆大学 学生实验报告 实验课程名称操作系统原理 开课实验室DS1501 学院软件学院年级2013专业班软件工程2 班学生姓名胡其友学号20131802 开课时间2015至2016学年第一学期 总成绩 教师签名洪明坚 软件学院制

《操作系统原理》实验报告 开课实验室:年月日学院软件学院年级、专业、班2013级软件工 程2班 姓名胡其友成绩 课程名称操作系统原理 实验项目 名称 指导教师洪明坚 教师 评语教师签名:洪明坚年月日 1.实验目的: ?进入实验环境 –双击expenv/setvars.bat ?检出(checkout)EPOS的源代码 –svn checkout https://www.doczj.com/doc/e017463917.html,/svn/epos ?编译及运行 –cd epos/app –make run ?清除所有的临时文件 –make clean ?调试 –make debug ?在“Bochs Enhanced Debugger”中,输入“quit”退出调试 –调试指令,请看附录A 2.实验内容: ?编写系统调用“time_t time(time_t *loc)” –功能描述 ?返回从格林尼治时间1970年1月1日午夜起所经过的秒数。如果指针loc 非NULL,则返回值也被填到loc所指向的内存位置 –数据类型time_t其实就是long ?typedef long time_t; 3.实验步骤: ?Kernel space –K1、在machdep.c中,编写系统调用的实现函数“time_t sys_time()”,计算用户秒数。需要用到 ?变量g_startup_time,它记录了EPOS启动时,距离格林尼治时间1970年1午夜的秒数 ?变量g_timer_ticks

四种实时操作系统特性进行分析和比较

四种实时操作系统特性进行分析和比较 https://www.doczj.com/doc/e017463917.html,2006年11月18日21:55ChinaByte 本文对四种实时操作系统(RTOS)特性进行分析和比较。它们是:Lynx实时系统公司的LynxOS、QNX软件系统有限公司的QNX以及两种具有代表性的实时Linux——新墨西哥工学院的RT-Linux和堪萨斯大学的KURT-Linux。 近年来,实时操作系统在多媒体通信、在线事务处理、生产过程控制、交通控制等各个领域得到广泛的应用,因而越来越引起人们的重视。 基本特征概述 *QNX是一个分布式、嵌入式、可规模扩展的实时操作系统。它遵循POSIX.1 (程序接口)和POSIX.2(Shell和工具)、部分遵循POSIX.1b(实时扩展)。它最早开发于1980年,到现在已相当成熟。 *LynxOS是一个分布式、嵌入式、可规模扩展的实时 操作系统,它遵循POSIX.1a、POSIX.1b和POSIX.1c标准。它最早开发于1988年。 *RT-Linux是一个嵌入式硬实时操作系统,它部分支持POSIX.1b标准。 *KURT-Linux不是为嵌入式应用设计的,不同于硬(hard)实时/软(soft)实时应用,他们提出“严格(firm)”实时应用的概念,如一些多媒体应用和ATM网络应用,KURT是为这样一些应用设计的“严格的”实时系统。 体系结构异同 实时系统的实现多为微内核体系结构,这使得核心小巧而可靠,易于ROM固化,并可模块化扩展。微内核结构系统中,OS服务模块在独立的地址空间运行,所以,不同模块的内存错误便被隔离开来。但它也有弱点,进程间通信和上下文切换的开销大大增加。相对于大型集成化内核系统来说,它必须靠更多地进行系统调用来完成相同的任务。 *QNX是一个微内核实时操作系统,其核心仅提供4种服务:进程调度、进程间通信、底层网络通信和中断处理,其进程在独立的地址空间运行。所有其它OS服务,都实现为协作的用户进程,因此QNX核心非常小巧(QNX4.x大约为12Kb)而且运行速度极快。 *LynxOS目前还不是一个微内核结构的操作系统,但它计划使用所谓的“Galaxy”技术将其从大型集成化内核改造成微内核,这一技术将在LynxOS 3.0中引入。新的28Kb微内核提供以下服务:核心启动和停止、底层内存管理、出错处理、中断处理、多任务、底层同步和互斥支持。

操作系统实验3答案

实验三操作系统进程管理 一、实验目的 1) 掌握系统进程的概念,加深对Linux / UNIX进程管理的理解。 2) 学会使用ps命令和选项。 3) 列出当前shell中的进程。 4) 列出运行在系统中的所有进程。 5) 根据命令名搜索特定的进程。 6) 使用kill命令终止进程。 7) 根据用户名查找和终止进程。 二、实验内容和相应的答案截图,三、实验结果分析 步骤1:创建一个普通用户(参见实验二),以普通用户身份登录进入GNOME。 步骤2:打开一个“终端”窗口(参见实验二)。 步骤3:回顾系统进程概念,完成以下填空: 1) Linux系统中,几乎每一个启动的进程,都会由内核分配一个唯一的__PID__进程标识符,用于跟踪从进程启动到进程结束。 2) 当启动新进程的时候,内核也给它们分配系统资源,如__内存_和__CPU_。 3) 永远不向父进程返回输出的进程叫做__僵进程__。 4) 由父进程派生出来的进程叫做____子___进程。 5) ___父_进程是一个派生另一个进程的进程。 6) 运行用于提供服务的Linux系统进程是_______________。 7) 如果父进程在子进程之前结束,它创建了一个______________进程。 步骤4:回顾ps命令和信息。基本的ps命令显示当前shell中的进程信息,用户只能够查看当前终端窗口中初始化的进程。输入ps命令,将结果填入表3-3中。 表3-3 实验记录 下面,在当前终端窗口中,练习使用给出的每个选项的ps命令。

输入ps -f 命令,显示运行在系统中的某个进程的完全信息,填入表3-4中。 表3-4 实验记录 步骤5:列出系统中运行的所有进程。 输入ps -ef 命令,显示运行在系统中的各个进程的完全信息。执行该命令,并与ps –f 命令的输出结果对照,一致吗?有何不同? 答:不一致,后者显示了所有进程的完全可用信息,多了很多。 分析当前终端窗口中的输出结果,记录下来用于写实验报告。 a. 显示了多少个进程?答:59 b. 进程ID的PID是什么? c. 启动进程的命令(CMD) 是什么?答:sched d. 请观察,什么命令的PID号是1?答:init[5] e. 执行ps –ef >aaa命令,将ps命令的输出送到文本文件aaa。再次运行cat aaa | wc命令,计算进程的数目。其中,cat是显示文本文件命令。“|”是管道命令,就是将前一个命令的输出作为后一个命令的输入。wc 命令用来计算文本的行数,第一个数字显示的是行的数目,可以用来计算进程的数目。计算出进程数目并做记录。 执行man ps命令,可以打开Linux用户命令手册。了解ps命令的用法。输入wq命令可退出用户手册的阅读。man命令可以执行吗?结果如何? 答:Man ps时出现

操作系统原理实验-系统内存使用统计5

上海电力学院 计算机操作系统原理 实验报告 题目:动态链接库的建立与调用 院系:计算机科学与技术学院 专业年级:信息安全2010级 学生姓名:李鑫学号:20103277 同组姓名:无 2012年11 月28 日上海电力学院

实验报告 课程名称计算机操作系统原理实验项目线程的同步 姓名李鑫学号20103277 班级2010251班专业信息安全 同组人姓名无指导教师姓名徐曼实验日期2012/11/28 实验目的和要求: (l)了解Windows内存管理机制,理解页式存储管理技术。 (2)熟悉Windows内存管理基本数据结构。 (3)掌握Windows内存管理基本API的使用。 实验原理与内容 使用Windows系统提供的函数和数据结构显示系统存储空间的使用情况,当内存和虚拟存储空间变化时,观察系统显示变化情况。 实验平台与要求 能正确使用系统函数GlobalMemoryStatus()和数据结构MEMORYSTATUS了解系统内存和虚拟空间使用情况,会使用VirtualAlloc()函数和VirtualFree()函数分配和释放虚拟存储空间。 操作系统:Windows 2000或Windows XP 实验平台:Visual Studio C++ 6.0 实验步骤与记录 1、启动安装好的Visual C++ 6.0。 2、选择File->New,新建Win32 Console Application程序, 由于内存分配、释放及系统存储 空间使用情况均是Microsoft Windows操作系统的系统调用,因此选择An application that support MFC。单击确定按钮,完成本次创建。 3、创建一个支持MFC的工程,单击完成。

操作系统实验报告

《操作系统原理》实验报告 实验项目名称:模拟使用银行家算法判断系统的状态 一、实验目的 银行家算法是操作系统中避免死锁的算法,本实验通过对银行家算法的模拟,加强对操作系统中死锁的认识,以及如何寻找到一个安全序列解除死锁。 二、实验环境 1、硬件:笔记本。 2、软件:Windows 7 , Eclipse。 三、实验内容 1.把输入资源初始化,形成资源分配表; 2.设计银行家算法,输入一个进程的资源请求,按银行家算法步骤进行检查; 3.设计安全性算法,检查某时刻系统是否安全; 4.设计显示函数,显示资源分配表,安全分配序列。 四、数据处理与实验结果 1.资源分配表由进程数组,Max,Allocation,Need,Available 5个数组组成; 实验采用数据为下表: 2.系统总体结构,即菜单选项,如下图

实验的流程图。如下图 3.实验过程及结果如下图所示

1.首先输入进程数和资源类型及各进程的最大需求量 2.输入各进程的占有量及目前系统的可用资源数量 3.初始化后,系统资源的需求和分配表 4.判断线程是否安全

5.对线程进行死锁判断 五、实验过程分析 在实验过程中,遇到了不少问题,比如算法无法回滚操作,程序一旦执行,必须直接运行到单个任务结束为止,即使产生了错误,也必须等到该项任务结束才可以去选择别的操作。但总之,实验还是完满的完成了。 六、实验总结 通过实验使我对以前所学过的基础知识加以巩固,也对操作系统中抽象理论知识加以理解,例如使用Java语言来实现银行家算法,在这个过程中更进一步了解了银行家算法,通过清晰字符界面能进行操作。不过不足之处就是界面略显简洁,对于一个没有操作过计算机的人来说,用起来可能还是有些难懂。所以,以后会对界面以及功能进行完善,做到人人都可以看懂的算法。

嵌入式实时操作系统vxworks实验教程[1]

???VxWorks 偠 ? Laboratory Tutorial for Embedded Real ˉtime Operating System VxWorks ?? ? ? ? ? ? ? 2003 10

???VxWorks 偠 ? ? 1 ???? (1) 1.1 ?? (1) 1.2 ??? (7) 2 ? MPC860 (16) 3 ???VxWorks ? ? Tornado (25) 3.1 ???VxWorks (25) 3.2 Tornado? ? (43) 4 VxWorks?BootRom (48) 5 偠 (55) 5.1 偠??Tornado??? (55) 5.2 偠?? ??? ? ? (74) 5.3 偠?? ? ? ?? (78) 5.4 偠 ?? ??? (101) 5.5 偠?? ?????? ?? (110) 5.6 偠 ? ?????? ?? (116) ? A hwa-xpc860 偠 (120)

1 ???? ?? ?? 催? ?? ??? ?? ? ? ?? ??Ё?????? ? ?? ?? ? ? ?? ?? (Embebdded computer) Ё??? ?? ? ??? ⑤?20??60 ?? ????? ? ????? ? 1.1.1 ???? ??? ?? ? Н? ??? ????? ?? ?? ???? ???? ?? ?? ?? ?? ???? ??? ????? ? ?????BIOS? ? ? ???? ?催 ? ? ? ㄝ???? ? ??? ? ? ? ?????????? ???? ?? ? ? ? ? ???? ?? ? ? ???? ?ㄝ???? ???? ??? ? ? ??? ? ???? ? ? ?? ㄝ ?? ? ??? ? ?? ? (control)???Mointer) ??(Managemet)ㄝ ?? 1.1.2 ? ?????? ? ? 1.1. 2.1 ? ?? ? ?? ??4?? ? 1? ? ? ? ?? ? ? ???Ё ????? ???? ?? ? ? ?? ?2? ? ??? ?? ?????? ? ????? ??? П? ??? ??????? ? ?? ???? ? 3? ? ? ? ????? ?? ? 催 ? ? ? 4? ? 乏 ? ?? ?? ? ? ? ??? ? ? Ё??∴??? ?? ?? ?? ? mW??uW??1.1.2.2 ? ???? ???? ?? ?? ? ? ?? ? ??? ?? ? ? ? ? ???1000 ??????? 30 ?? ?

操作系统实验报告_实验五

实验五:管道通信 实验内容: 1.阅读以下程序: #include #include #include main() { int filedes[2]; char buffer[80]; if(pipe(filedes)<0) //建立管道,filedes[0]为管道里的读取端,filedes[1]则为管道的写入端 //成功则返回零,否则返回-1,错误原因存于errno中 err_quit(“pipe error”); if(fork()>0){ char s[ ] = “hello!\n”; close(filedes[0]); //关闭filedes[0]文件 write(filedes[1],s,sizeof(s)); //s所指的内存写入到filedes[1]文件内 close(filedes[1]); //关闭filedes[0]文件 }else{ close(filedes[1]); read(filedes[0],buffer,80); //把filedes[0]文件传送80个字节到buffer缓冲区内 printf(“%s”,buffer); close(filedes[0]); } } 编译并运行程序,分析程序执行过程和结果,注释程序主要语句。

2.阅读以下程序: #include #include #include main() { char buffer[80]; int fd; unlink(FIFO); //删除FIFO文件 mkfifo(FIFO,0666); //FIFO是管道名,0666是权限 if(fork()>0){ char s[ ] = “hello!\n”;

实时操作系统包括硬实时和软实时的区别

一.什么是真正的实时操作系统 做嵌入式系统开发有一段时间了,做过用于手机平台的嵌入式Linux,也接触过用于交换机、媒体网关平台的VxWorks,实际应用后回过头来看理论,才发现自己理解的肤浅,也发现CSDN 上好多同学们都对实时、嵌入式这些概念似懂非懂,毕竟如果不做类似的产品,平时接触的机会很少,即使做嵌入式产品开发,基本也是只管调用Platformteam封装好的API。所以在此总结一下这些概念,加深自己的理解,同时也给新手入门,欢迎大家拍砖,争取写个连载,本文先总结一下实时的概念,什么是真正的实时操作系统? 1. 首先说一下实时的定义及要求: 参见 Donal Gillies 在 Realtime Computing FAQ 中提出定义:实时系统指系统的计算正确性不仅取决于计算的逻辑正确性,还取决于产生结果的时间。如果未满足系统的时间约束,则认为系统失效。

一个实时操作系统面对变化的负载(从最小到最坏的情况)时必须确定性地保证满足时间要求。请注意,必须要满足确定性,而不是要求速度足够快!例如,如果使用足够强大的CPU,Windows在CPU空闲时可以提供非常短的典型中断响应,但是,当某些后台任务正在运行时,有时候响应会变得非常漫长,以至于某一个简单的读取文件的任务会长时间无响应,甚至直接挂死。这是一个基本的问题:并不是Windows不够快或效率不够高,而是因为它不能提供确定性,所以,Windows不是一个实时操作系统。 根据实际应用,可以选择采用硬实时操作系统或软实时操作系统,硬实时当然比软实时好,但是,如果你的公司正在准备开发一款商用软件,那请你注意了,业界公认比较好的VxWorks(WindRiver开发),会花光你本来就很少的银子,而软实时的操作系统,如某些实时Linux,一般是开源免费的,我们公司本来的产品就是基于VxWorks的,现在业界都在CostReduction,为了响应号召,正在调研如何把平台换成免费的嵌入式实时Linux。同学们,如何选择,自己考虑吧:-)

操作系统实验心得(精选多篇)

操作系统实验心得 每一次课程设计度让我学到了在平时课堂不可能学到的东西。所以我对每一次课程设计的机会都非常珍惜。不一定我的课程设计能够完成得有多么完美,但是我总是很投入的去研究去学习。所以在这两周的课设中,熬了2个通宵,生物钟也严重错乱了。但是每完成一个任务我都兴奋不已。一开始任务是任务,到后面任务就成了自己的作品了。总体而言我的课设算是达到了老师的基本要求。总结一下有以下体会。 1、网络真的很强大,用在学习上将是一个非常高效的助手。几乎所有的资料都能够在网上找到。从linux虚拟机的安装,到linux的各种基本命令操作,再到gtk的图形函数,最后到文件系统的详细解析。这些都能在网上找到。也因为这样,整个课程设计下来,我浏览的相关网页已经超过了100个(不完全统计)。当然网上的东西很乱很杂,自己要能够学会筛选。不能决定对或错的,有个很简单的方法就是去尝试。就拿第二个实验来说,编译内核有很多项小操作,这些小操作错了一项就可能会导致编译的失败,而这又是非常要花时间的,我用的虚拟机,编译一次接近3小时。所以要非常的谨慎,尽量少出差错,节省时间。多找个几个参照资料,相互比较,慢慢研究,最后才能事半功倍。 2、同学间的讨论,这是很重要的。老师毕竟比较忙。对于课程设计最大的讨论伴侣应该是同学了。能和学长学姐讨论当然再好不过了,没有这个机会的话,和自己班上同学讨论也是能够受益匪浅的。

大家都在研究同样的问题,讨论起来,更能够把思路理清楚,相互帮助,可以大大提高效率。 3、敢于攻坚,越是难的问题,越是要有挑战的心理。这样就能够达到废寝忘食的境界。当然这也是不提倡熬夜的,毕竟有了精力才能够打持久战。但是做课设一定要有状态,能够在吃饭,睡觉,上厕所都想着要解决的问题,这样你不成功都难。 4、最好在做课设的过程中能够有记录的习惯,这样在写实验报告时能够比较完整的回忆起中间遇到的各种问题。比如当时我遇到我以前从未遇到的段错误的问题,让我都不知道从何下手。在经过大量的资料查阅之后,我对段错误有了一定的了解,并且能够用相应的办法来解决。 在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的 1)访问系统数据区,尤其是往系统保护的内存地址写数据,最常见就是给一个指针以0地址 2)内存越界(数组越界,变量类型不一致等) 访问到不属于你的内存区域 3)其他 例如: <1>定义了指针后记得初始化,在使用的时候记得判断是否为 null <2>在使用数组的时候是否被初始化,数组下标是否越界,数组元素是否存在等 <3>在变量处理的时候变量的格式控制是否合理等

操作系统原理实验四

实验4 进程控制 1、实验目的 (1)通过对WindowsXP进行编程,来熟悉和了解系统。 (2)通过分析程序,来了解进程的创建、终止。 2、实验工具 (1)一台WindowsXP操作系统的计算机。 (2)计算机装有Microsoft Visual Studio C++6.0专业版或企业版。 3、预备知识 (3)·CreateProcess()调用:创建一个进程。 (4)·ExitProcess()调用:终止一个进程。 4、实验编程 (1)编程一利用CreateProcess()函数创建一个子进程并且装入画图程序(mspaint.exe)。阅读该程序,完成实验任务。源程序如下: # include < stdio.h > # include < windows.h > int main(VOID) ﹛STARTUPINFO si; PROCESS INFORMA TION pi; ZeroMemory(&si,sizeof(si)); Si.cb=sizeof(si); ZeroMemory(&pi,sizeof(pi)); if(!CreateProcess(NULL, “c: \ WINDOWS\system32\ mspaint.exe”, NULL, NULL, FALSE, 0, NULL, NULL, &si,&pi)) ﹛fprintf(stderr,”Creat Process Failed”); return—1; ﹜ WaitForSingleObject(pi.hProcess,INFINITE); Printf(“child Complete”); CloseHandle(pi.hProcess); CloseHandle(pi hThread); ﹜

操作系统实验报告

《计算机操作系统》实验报告 教师: 学号: 姓名: 2012年3月6日 计算机学院

实验题目:请求页式存储管理(三) ----------------------------------------------------------------------------- 实验环境:VC6.0++ 实验目的:学生应独立地用高级语言编写几个常用的存储分配算法,并设计一个存储管理的模拟程序,对各种算法进行分析比较,评测其性能优劣,从而加深对这些算法的了解。实验内容: (1)编制和调试示例给出的请求页式存储管理程序,并使其投入运行。 (2)增加1~2种已学过的淘汰算法,计算它们的页面访问命中率。试用各种算法的命中率加以比较分析。(增加了FIFO) 操作过程: (1)产生随机数 (2)输入PageSize(页面大小1 /2/4/8 K) (pageno[i]=int(a[i]/1024)+1) (3)菜单选择

(4)OPT/ LRU/FIFO演示(pagesize=1K)

(5) 过程说明(PAGESIZE = 4K ) OPT :最佳置换算法(淘汰的页面是以后永不使用,或许是在最长时间内不再被访问的页面) //在Table 表中如果未找到,记录每个元素需要找的长度 //全部table 中元素找完长度,然后进行比较,找出最大的,进行淘汰 int max=0; int out; for(k=0;kmax){ max = table_time[k]; out = k; } }//找出最长时间,进行替换 table[out]=pageno[i]; page_out++;

操作系统实验报告

操作系统实验报告 Document number:NOCG-YUNOO-BUYTT-UU986-1986UT

许昌学院 《操作系统》实验报告书学号: 姓名:闫金科 班级:14物联网工程 成绩: 2016年02月

实验一Linux的安装与配置 一、实验目的 1.熟悉Linux系统的基本概念,比如Linux发行版、宏内核、微内核等。 2.掌握Linux系统的安装和配置过程,初步掌握Linux系统的启动和退出方 法。 3.熟悉Linux系统的文件系统结构,了解Linux常用文件夹的作用。 二、实验内容 1.从网络上下载VMware软件和两个不同Linux发行版镜像文件。 2.安装VMware虚拟机软件。 3.在VMware中利用第一个镜像文件完成第一个Linux的安装,期间完成网络 信息、用户信息、文件系统和硬盘分区等配置。 4.在VMware中利用第二个镜像文件完成第二个Linux的安装,并通过LILO或 者GRUB解决两个操作系统选择启动的问题。 5.启动Linux系统,打开文件浏览器查看Linux系统的文件结构,并列举出 Linux常用目录的作用。 三、实验过程及结果 1、启动VMware,点击新建Linux虚拟机,如图所示: 2、点击下一步,选择经典型,点击下一步在选择客户机页面选择 Linux,版本选择RedHatEnterpriseLinux5,如图所示: 3、点击下一步创建虚拟机名称以及所要安装的位置,如图所示: 4、点击下一步,磁盘容量填一个合适大小,此处选择默认值大小 10GB,如图所示: 5、点击完成,点击编辑虚拟机设置,选择硬件选项中的CD-ROM (IDE...)选项,在右侧连接中选择“使用ISO镜像(I)”选项,点 击“浏览”,找到Linux的镜像文件,如图所示:

实时操作系统实验

实时操作系统实验报告 专业:10通信工程 学号:20100306110 姓名: 汪洁 指导老师:申屠浩

实验一任务管理实验 实验目的: 1.理解任务管理的基本原理,了解任务的各个基本状态及其变迁过程; 2.掌握μC/OS-II 中任务管理的基本方法(挂起、解挂); 3.熟练使用μC/OS-II 任务管理的基本系统调用。 实验要求与思路: 为了体现任务的各个基本状态及其变迁过程,本实验设计了T0、T1 和T3 三个任务,它们交替运行,如图所示 说明: 在系统完成初始化后,可以先创建并启动优先级最低的TaskStart,由它创 建其他3 个应用任务T0、T1 和T2,之后整个系统的运行流程如下: 1)优先级最高的T0 开始执行,之后T0 挂起自己; 2)然后系统调度选中T1 开始执行,之后T1 挂起自己; 3)接着系统调度选中T2,之后唤醒T0; 4)如此循环 实验程序: #include "includes.h" #define TASK_STK_SIZE 512 OS_STK TaskStk1[TASK_STK_SIZE]; OS_STK TaskStk2[TASK_STK_SIZE]; OS_STK TaskStk3[TASK_STK_SIZE]; OS_STK TaskStartStk[TASK_STK_SIZE]; void Task1(void *data); void Task2(void *data); void Task3(void *data); /* Function prototypes of tasks*\ void TaskStart(void *data); /* Function prototypes of Startup task */

嵌入式实时操作系统实验报告

嵌入式实时操作系统实验报告 任务间通信机制的建立 系别计算机与电子系 专业班级***** 学生姓名****** 指导教师 ****** 提交日期 2012 年 4 月 1 日

一、实验目的 掌握在基于嵌入式实时操作系统μC/OS-II的应用中,任务使用信号量的一般原理。掌握在基于优先级的可抢占嵌入式实时操作系统的应用中,出现优先级反转现象的原理及解决优先级反转的策略——优先级继承的原理。 二、实验内容 1.建立并熟悉Borland C 编译及调试环境。 2.使用课本配套光盘中第五章的例程运行(例5-4,例5-5,例5-6),观察运行结果,掌握信号量的基本原理及使用方法,理解出现优先级反转现象的根本原因并提出解决方案。 3.试编写一个应用程序,采用计数器型信号量(初值为2),有3个用户任务需要此信号量,它们轮流使用此信号量,在同一时刻只有两个任务能使用信号量,当其中一个任务获得信号量时向屏幕打印“TASK N get the signal”。观察程序运行结果并记录。 4. 试编写一个应用程序实现例5-7的内容,即用优先级继承的方法解决优先级反转的问题,观察程序运行结果并记录。 5.在例5-8基础上修改程序增加一个任务HerTask,它和YouTask一样从邮箱Str_Box里取消息并打印出来,打印信息中增加任务标识,即由哪个任务打印的;MyTask发送消息改为当Times为5的倍数时才发送,HerTask接收消息采用无等待方式,如果邮箱为空,则输出“The mailbox is empty”, 观察程序运行结果并记录。 三、实验原理 1. 信号量 μC/OS-II中的信号量由两部分组成:一个是信号量的计数值,它是一个16位的无符号整数(0 到65,535之间);另一个是由等待该信号量的任务组成的等待任务表。用户要在OS_CFG.H中将OS_SEM_EN开关量常数置成1,这样μC/OS-II 才能支持信号量。

相关主题
文本预览
相关文档 最新文档