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

操作系统实验指导

操作系统实验指导
操作系统实验指导

《计算机操作系统》

实验指导

苏州科技学院电子与信息工程学院

计算机工程系

二O一四年九月

目录

Linux 平台

实验一命令解释程序 (2)

实验二进程管理 (3)

实验三进程间通信 (5)

实验四存储管理 (14)

实验五设备管理 (22)

实验六软盘I/O (32)

实验七文件系统 (41)

Windows 平台

实验一进程同步 (42)

实验二内存管理实验 (44)

实验三快速文件系统实习 (46)

实验四进程之间通信 (47)

实验五Windows 应用程序与动态链接库 (49)

实验六WDM驱动程序开发 (50)

实验一命令解释程序

实验名称:命令解释程序实验项目性质:设计性

所涉及课程:操作系统计划学时:2

承担实验室:计算机实验室实验环境要求:Redhat Linux

适用专业:计算机科学与技术

一、实验目的

1、通过本实验熟悉UNIX/LINUX操作系统及C语言。

2、熟悉系统调用的编程方法。

二、实验预备内容

查阅实验中相关函数调用的用法(可用man命令):

gets, strcspn, strncpy, strcmp, system等

三、实验内容

利用C语言编写一个微型命令解释程序minishell.c,该程序可接收并解释以下命令:

(1) dir 列出当前目录

(2) cop file1 file2 拷贝文件

(3) era filename 删除文件

(4) disp string 显示字符串

(5) end 结束,退出

要求:

(1)检查命令的合法性,如果有错误,显示出错信息,等待重新输入;

(2)命令前后有空格示为合法命令。

四、示例程序minishell.c

//文件名minishell.cpp

//功能小型SHELL命令解释程序

//开发环境

#define true 1

#define flase 0

#include

#include

#include

void main()

{

char cmdl[80];

char *scwt[]={"exit","dir","time"};

static int cmdnum=3; //可用的命令数

char cmd[80];

int j , n;

while(true)

{

printf("Please input command: ");

gets(cmdl); //取命令行输入

n=strcspn(cmdl," "); //取命令命令部分

if (n>0||strlen(cmdl)>0)

{ strnexicpy(cmd,cmdl,n);

cmd[n]='\0';

for(j=0;j

if (strcmp(cmd,scwt[j])==0)

break;

if (j==0) //是exit命令?

exit(0);

if (j

{

system(cmdl);

continue;

}

printf("Bad command!\n"); //命令错

}

}

}

实验二进程管理

实验名称:进程管理实验项目性质:验证性

所涉及课程:操作系统计划学时:2

承担实验室:计算机实验室实验环境要求:Redhat Linux 适用专业:计算机科学与技术

一、实验目的

1、加深对进程概念的理解,明确进程和程序的区别。

2、进一步认识并发执行的实质。

3、分析进程竞争资源的现象,学习解决进程互斥的方法。

二、实验预备内容

1、阅读Linux 的sched.h源代码文件,加深对进程管理概念的理解。

2、阅读Linux 的fork.c源代码文件,分析进程的创建过程。

3、查阅系统调用fork(), lockf(),exit(), wait() , sleep()等的用法。

三、实验内容

1、进程的创建

编写一段程序,使用系统调用fork()创建两个子进程。让父进程显示字符串‘Parent:’;两个子进程分别显示字符串‘Child1:’和‘Child2:’。多次运行此程序,观察屏幕显示的结果,并分析原因。

2、进程控制

修改已编写的程序,将输出多次重复的一句话,观察程序执行时在屏幕上显示的结果,并分析原因。

若在程序中使用系统调用lockf()来给每一个进程加锁,可以实现进程之间的互斥,观察屏幕显示的结果,并分析原因。

四、函数调用示例

1、系统调用fork()

原型:#include

#include

pid_t fork(void);

返回值:子进程中为0,父进程中为子进程I D,出错为-1

由fork创建的新进程被称为子进程(child process)。该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程ID。将子进程I D返回给父进程的理由是:因为一个进程的子进程可以多于一个,所以没有一个函数使一个进程可以获得其所有子进程的进程ID。fork使子进程得到返回值0的理由是:一个进程只会有一个父进程,所以子进程总是可以调用getppid以获得其父进程的进程ID (进程ID 0总是由交换进程使用,所以一个子进程的进程ID不可能为0 )。

子进程和父进程继续执行fork之后的指令。子进程是父进程的复制品。例如,子进程获得父进程数据空间、堆和栈的复制品。注意,这是子进程所拥有的拷贝。父、子进程并不共享这些存储空间部分。如果正文段是只读的,则父、子进程共享正文段。

2、fork()调用示例

#include

main(){

int p1,p2;

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

if (p1==0) //是子进程?

putchar('b');

else //父进程

{

putchar('a');

}

}

实验三进程间通信

实验名称:进程间通信实验项目性质:综合性

所涉及课程:操作系统计划学时:4

承担实验室:计算机实验室实验环境要求:Redhat Linux

适用专业:计算机科学与技术

一、实验目的

1、了解和熟悉Linux支持的消息通信机制、管道道通信、共享存储区机制及信息量机制。

2、掌握利用Linux系统的进程通信机制(IPC)实现进程间交换数据的方法。

二、实验预备内容

1、阅读Linux系统的msg.c、sem.c和shm.c等源码文件,熟悉Linux的三种通信机制。

2、查阅系统调用pipe(),write(),read(),exit(), wait() , sleep()等的用法。

三、实验内容

1、进程通信

编写一段程序,实现进程的管道通信。

使用系统调用pipe()建立一条管道线:两个子进程P1和P2分别向管道各写一句话:Child 1 is sending a message!

Child 2 is sending a message!

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

要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。(可以通过sleep()将自身进入睡眠)

2、消息的创建,发送和接收.

(1) 使用系统调用msgget(), msgsnd(), msgsrv()及msgctl()编制一长度为1K的消息(如个人通信录信息)的发送和接收程序.

①观察上面程序,说明控制消息队列系统调用msgctl()

②共享存储区的发送和接收。

(2) 使用共享存储区相关的系统调用shmget(),shmat(),sgmdt(),shmctl(),编制一个与上述功能相同的程序.

(3) 比较上述两种消息通信机制中数据传输的时间。

四、函数调用示例

1、管道

1)系统调用pipe()

原型:int pipe( int fd[2] );

返回值:如果系统调用成功,返回0

如果系统调用失败返回- 1:errno = EMFILE (没有空闲的文件描述符)

EMFILE (系统文件表已满)

EFAULT (fd数组无效)

参数是一个包括两个整数的数组。如果系统调用成功,此数组将包括管道使用的两个文件描述符。创建一个管道之后,一般情况下进程将产生一个新的进程。注意fd[0] 用于读取管道,fd[1] 用于写入管道。

一旦创建了管道,就可以创建一个新的子进程:

2)pipe()调用示例

#include

main()

{

int id,fd[2];

char buf[50],s[50];

pipe(fd);

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

if (id==0)

{

sprintf(buf,"Child is sending message!");

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

exit(0);

}

else

{

wait(0);

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

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

exit(0);

}

}

2、共享内存相关

1)系统调用:shmget( ) ;

原型:int shmget ( key_t key, int size, int shmflg );

返回值:如果成功,返回共享内存段标识符。

如果失败,则返回- 1:errno = EINV AL (无效的内存段大小)

EEXIST (内存段已经存在,无法创建)

EIDRM (内存段已经被删除)

ENOENT (内存段不存在)

EACCES (权限不够)

ENOMEM (没有足够的内存来创建内存段) 系统调用shmget() 中的第一个参数是关键字值(它是用系统调用ftok( )返回的)。其他的操作都要依据shmflg中的命令进行。

IPC_CREAT 如果系统内核中没有共享的内存段,则创建一个共享的内存段。

IPC_EXCL 当和IPC_CREAT一同使用时,如果共享内存段已经存在,则调用失败。

当IPC_CREAT单独使用时,系统调用shmget()要么返回一个新创建的共享内存段的标识符,要么返回一个已经存在的共享内存段的关键字值。如果IPC_EXCL和IPC_CREAT一同使用,则要么系统调用新创建一个共享的内存段,要么返回一个错误值- 1。IPC_EXCL单独使用没有意义。

2)系统调用shmat()

原型:int shmat ( int shmid, char *shmaddr, int shmflg);

返回值:如果成功,则返回共享内存段连接到进程中的地址。

如果失败,则返回- 1:errno=EINV AL(无效的IPCID值或者无效的地址)

ENOMEM (没有足够的内存)

EACCES (存取权限不够)

如果参数addr的值为0,那么系统内核则试图找出一个没有映射的内存区域。推荐使用这种方法。可指定一个地址,但这通常是为了加快对硬件设备的存取,或者解决和其他程序的冲突。

3)系统调用:shmctl() ;

原型:int shmctl ( int shmqid, int cmd, struct shmid_ds *buf );

返回值:0 ,如果成功。

- 1,如果失败:errno = EACCES (没有读的权限,同时命令是IPC_ STAT )

EFAULT (buf指向的地址无效,同时命令是IPC_SET

和IPC_STAT )

EIDRM (内存段被移走)

EINV AL (shmqid 无效)

EPERM (使用IPC_SET 或者IPC_RMID 命令,但调用

进程没有写的权限)

参数cmd 操作命令:

IPC_STA T 读取一个内存段的数据结构shmid_ds,并将它存储在b u f参数指向的地址中。

IPC_SET 设置内存段的数据结构shmid_ds中的元素ipc_perm的值。从参数buf中得到要设置的值。

IPC_RMID 标志内存段为移走。

命令IPC_RMID并不真正从系统内核中移走共享的内存段,而是把内存段标记为可移除。进程调用系统调用shmdt()脱离一个共享的内存段。

4)系统调用:shmdt();

调用原型:int shmdt ( char *shmaddr );

返回值:如果失败,则返回- 1:errno = EINV AL (无效的连接地址)

当一个进程不在需要共享的内存段时,它将会把内存段从其地址空间中脱离。但这不等于将共享内存段从系统内核中移走。当进程脱离成功后,数据结构shmid_ds中元素shm_nattch将减1。当此数值减为0以后,系统内核将物理上把内存段从系统内核中移走。

用共享内存的实例:

(1) 将字符串写入到内存段中

(2) 从内存段中读取字符串

(3) 改变内存段的权限

(4) 删除内存段

5)使用示例shmtool.c

#include

#include

#include

#include

#define SEGSIZE 100

main(int argc, char *argv[])

{ key_t key;

int shmid, cntr;

char *segptr;

if(argc == 1)

usage(); /* Create unique key via call to ftok() */

key = ftok(".", 'S');

/* Open the shared memory segment - create if necessary */

if((shmid = shmget(key, SEGSIZE, IPC_CREAT|IPC_EXCL|0666)) == -1)

{

printf("Shared memory segment exists - opening as client\n");

/* Segment probably already exists - try as a client */

if((shmid = shmget(key, SEGSIZE, 0)) == -1)

{

perror("shmget");

exit(1);

}

}

else

{

printf("Creating new shared memory segment\n");

}

/* Attach (map) the shared memory segment into the current process */ if((segptr = shmat(shmid, 0, 0)) == -1)

{

perror("shmat");

exit(1);

}

switch(tolower(argv[1][0]))

{

case 'w': writeshm(shmid, segptr, argv[2]);

break;

case 'r': readshm(shmid, segptr);

break;

case 'd': removeshm(shmid);

break;

case 'm': changemode(shmid, argv[2]);

break;

default: usage();

}

}

writeshm(int shmid, char *segptr, char *text)

{

strcpy(segptr, text);

printf("Done...\n");

}

readshm(int shmid, char *segptr)

{

printf("segptr: %s\n", segptr);

}

removeshm(int shmid)

{

shmctl(shmid, IPC_RMID, 0);

printf("Shared memory segment marked for deletion\n");

}

changemode(int shmid, char *mode)

{

struct shmid_ds myshmds;

/* Get current values for internal data structure */

shmctl(shmid, IPC_STA T, &myshmds); /* Display old permissions */

printf("Old permissions were: %o\n", myshmds.shm_perm.mode);

/* Convert and load the mode */

sscanf(mode, "%o", &myshmds.shm_perm.mode); /* Update the mode */

shmctl(shmid, IPC_SET, &myshmds);

printf("New permissions are : %o\n", myshmds.shm_perm.mode);

}

usage()

{

fprintf(stderr, "shmtool - A utility for tinkering with shared memory\n");

fprintf(stderr, "\nUSAGE: shmtool (w)rite \n");

fprintf(stderr, " (r)ead\n");

fprintf(stderr, " (d)elete\n");

fprintf(stderr, " (m)ode change \n");

exit(1);

}

3、消息机制相关

1)消息缓冲区

数据结构msgbuf是消息数据的模板。虽然此数据结构需要用户自己定义,但了解系统中有这样一个数据结构是十分重要的。在linux/msg.h中,此数据结构是这样定义的:

/* message buffer for msgsnd and msgrcv calls */

struct msgbuf {

long mtype; /* type of message */

char mtext[1]; /* message text */

};

在数据结构msgbuf中共有两个元素:

mtype 指消息的类型,它由一个整数来代表,并且,它只能是整数。

mtext 是消息数据本身。

因为程序员自己可以重新定义此数据结构。请看下面重新定义的例子:

struct my_msgbuf {

long mtype; /* Message type */

long request_id; /* Request identifier */

struct client info; /* Client information structure */

};

在Linux系统中,这是在linux/msg.h中定义的:

#define MSGMAX 4056 /* <= 4056 */ /* max size of message (bytes) */

消息的最大的长度是4056个字节,其中包括mtype,它占用4个字节的长度。

2)系统调用msgget()

如果希望创建一个新的消息队列,或者希望存取一个已经存在的消息队列,你可以使用系统调用msgget( )。

系统调用:msgget();

原型:int msgget ( key_t key, int msgflg );

返回值:如果成功,返回消息队列标识符

如果失败,则返回- 1:errno =EACCESS (权限不允许)

EEXIST (队列已经存在,无法创建)

EIDRM (队列标志为删除)

ENOENT (队列不存在)

ENOMEM (创建队列时内存不够)

ENOSPC (超出最大队列限制)

系统调用msgget()中的第一个参数是关键字值(通常是由ftok( )返回的)。然后此关键字值将会和其他已经存在于系统内核中的关键字值比较。这时,打开和存取操作是和参数msgflg中的内容相关的。

参数msgflg:

IPC_CREAT 如果内核中没有此队列,则创建它。

IPC_EXCL 当和IPC_CREAT一起使用时,如果队列已经存在,则失败。

如果单独使用IPC_CREAT,则msgget( )要么返回一个新创建的消息队列的标识符,要么返回具有相同关键字值的队列的标识符。如果IPC_EXCL 和IPC_CREAT一起使用,则msgget()要么创建一个新的消息队列,要么如果队列已经存在则返回一个失败值- 1。IPC_EXCL单独使用是没有用处的。

3)系统调用:msgsnd();

原型:int msgsnd ( int msqid, struct msgbuf *msgp, int msgsz, int msgflg );

返回值:如果成功,0。

如果失败,-1 :errno = EAGAIN (队列已满,并且使用了IPC_NOW AIT )

EACCES (没有写的权限)

EFAULT (msgp 地址无效)

EIDRM (消息队列已经删除)

EINTR (当等待写操作时,收到一个信号)

EINV AL (无效的消息队列标识符,非正数

的消息类型,或者无效的消息长度)

ENOMEM (没有足够的内存复制消息缓冲区

第一个参数是消息队列标识符,它是由系统调用msgget返回的。第二个参数是msgp,是指向消息缓冲区的指针。参数msgsz中包含的是消息的字节大小,但不包括消息类型的长度(4个字节)。

参数msgflg可以设置为0(此时为忽略此参数),或者使用PC_NOWAIT。如果消息队列已满,那么此消息则不会写入到消息队列中,控制将返回到调用进程中。如果没有指明,调用进程将会挂起,直到消息可以写入到队列中。

4)系统调用:msgrcv( ) ;

原型:int msgrcv ( int msqid, struct msgbuf *msgp, int msgsz, long mtype, int msgflg );

返回值:如果成功,则返回复制到消息缓冲区的字节数。

如果失败,则返回- 1:errno = E2BIG (消息的长度大于msgsz ,没有MSG_NOERROR )

EACCES (没有读的权限)

EFAULT (msgp 指向的地址是无效的)

EIDRM (队列已经被删除)

EINTR (被信号中断)

EINV AL (msgqid 无效, 或者msgsz 小于0 )

ENOMSG (使用IPC_NOW AIT,

同时队列中的消息无法满足要求)

第一个参数用来指定将要读取消息的队列。第二个参数代表要存储消息的消息缓冲区的地址。第三个参数是消息缓冲区的长度,不包括mtype的长度,它可以按照如下的方法计算:msgsz = sizeof(struct mymsgbuf) - sizeof(long);

第四个参数是要从消息队列中读取的消息的类型。如果此参数的值为0,那么队列中最长时间的一条消息将返回,而不论其类型是什么。

5)系统调用:msgctl( ) ;

调用原型:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

返回:0 ,如果成功。

1,如果失败:errno = EACCES (没有读的权限同时cmd 是IPC_STAT )

EFAULT (buf 指向的地址无效)

EIDRM (在读取中队列被删除)

EINV AL (msgqid无效, 或者msgsz 小于0 )

EPERM (IPC_SET或者IPC_RMID 命令被使用,

但调用程序没有写的权限)

参数cmd :

IPC_STA T 读取消息队列的数据结构msqid_ds,并将其存储在buf指定的地址中。

IPC_SET 设置消息队列的数据结构msqid_ds中的ipc_perm元素的值。

这个值取自buf参数。

IPC_RMID 从系统内核中移走消息队列。

6)使用示例

(1) message.h

/* message.h*/

#ifndef MESSAGE_H

#define MESSAGE_H

struct mymsgbuf

{

long mtype;

char mtext[256];

};

#endif

(2) shm_server.c

/*shm_server.c*/

#include

#include

#include

#include

#include

#include

#include "message.h"

int msqid=-1;

void sig_handle(int signo)

{/*软中断*/

if (msqid!=-1)

msgctl(msqid,IPC_RMID,NULL);

printf("server quit...\n");

exit(0);

}

int main()

{

struct mymsgbuf msgbuf;

int left,right;

char c;

int length;

if ((msqid=msgget(999,0666))!=-1)

{

msgctl(msqid,IPC_RMID,NULL);

}

if ((msqid=msgget(999,IPC_CREAT|0666))==-1)

{

printf("error:getmsg\n");

exit(1);

}

signal(SIGINT,sig_handle); /*LINUX置软中断—CTRL-D*/ for (;;)

{

if (msgrcv(msqid,&msgbuf,256,1L,0)==-1)

{

printf("error:msgrcv\n");

exit(1);

}

length=strlen(msgbuf.mtext);

left=0;

right=length-1;

while(left

{

c=msgbuf.mtext[left];

msgbuf.mtext[left]=msgbuf.mtext[right];

msgbuf.mtext[right]=c;

left++;

right--;

}

msgbuf.mtext[length]='\0';

msgbuf.mtype=2;

if (msgsnd(msqid,&msgbuf,256,0)==-1)

{

printf("error:msgsnd");

exit(1);

}

}

msgctl(msqid,IPC_RMID,NULL);

exit(0);

}

(3) msg_client.c

/*msg_client.c*/

#include

#include

#include

#include

#include

#include "message.h"

int main()

{

struct mymsgbuf msgbuf;

int msqid;

if ((msqid=msgget(999,0666))==-1)

{

printf("Server is not running\n");

exit(1);

}

printf("Input a line:");

scanf("%s",msgbuf.mtext);

msgbuf.mtype=1;

if (msgsnd(msqid,&msgbuf,256,0)==-1)

{

printf("error:msgsnd\n");

exit(1);

}

if (msgrcv(msqid,&msgbuf,256,2L,0)==-1)

{

printf("error:msgrcv\n");

exit(1);

}

printf("The reversed line is:%s\n",msgbuf.mtext);

exit(0);

}

实验四存储管理

实验名称:存储管理实验项目性质:设计性

所涉及课程:操作系统计划学时:2

承担实验室:计算机实验室实验环境要求:Redhat Linux

适用专业:计算机科学与技术

一、实验目的

1、了解虚拟存储技术的特点,掌握请求页式存储管理的主要页面置换算法原理。

2、掌握请求页式存储管理中页面置换算法的模拟设计方法。

二、实验内容

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

①先进先出的算法(FIFO);

②最近最少少使用算法(LRR);

③最佳淘汰算法(OPT):选淘汰最不常用的页地址;

④最少访问页面算法(LFR);

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

(其中③④为选择内容)

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

三、实验指导

1、通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成:

①50%的指令是顺序执行的;

②25%的指令是均匀分布在前地址部分;

③25%的指令是均匀分布在后地址部分。

具体的实施方法是:

①在[1,319]指令地址之间随机选取一起点m;

②顺序执行一条指令,即执行地址为m十1的指令;

③在前地址[0,m十1]中随机选取一条指令并执行,该指令的地址为m’;

④顺序执行一条指令,其地址为m‘+1;

⑤在后地址[m’+2,319]中随机选取一条指令并执行;

③重复上述步骤①~⑤,直到执行320次指令。

2、将指令序列变换成为页地址流

设:①页面大小为IK;

②用户内存容量为4页到32页;

③用户虚存容量为32K。

在用户虚存中,按每K存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:

第0条~第9条指令为第0页(对应虚存地址为[0,9]);

第10条~第19条指令为第1页(对应虚存地址为[10,19]);

第310条~第319条指令为第31页(对应虚存地址为[310,319])。

按以上方式,用户指令可组成32页。

3、按实验要求计算并输出各种算法在不同内存容量下的命中率。

在本实验中,页地址流长度为320,页面失效次数为每次访问相应指令时,该指令所对应的页不在内存的次数。

4、随机数产生办法

关于随机数产生办法,Linux 或UNIX系统提供函数srand()和rand() 分别进行初始化和产生随机数。例如:

srand( );

语句可初始化一个随机数;

a[0]=10*rand( )/32767 * 319 +1;

a[1]=10*rand( )/32767 * a[0];

….

语句可用来产生a[0] 与a[1]中的随机数(rand()产生一个介于0—32767之间的整数)。

5、相关定义

(1)数据结构

1)、页面类型

typedef struct{

int pn,pfn,counter,time;

}pl_type;

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

2)、页面控制结构

struct pfc_struct {

int pn, pfn;

struct pfc_struct *next;

}

typedef struct pfc_struct pfc_type;

pfc_type pfc[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 diseffect:页面失效次数。

6、程序流程图〈略〉

7、示例程序

#define TRUE 1

#define FALSE 0

#define INV ALID -1

#define null 0

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

#define total_vp 32 /*虚页长*/

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

typedef struct{ /*页面结构*/

int pn,pfn,counter,time;

}pl_type;

pl_type pl[total_vp]; /*页面数组*/

struct pfc_struct{ /*页面控制结构*/

int pn,pfn;

struct pfc_struct *next;

};

typedef struct pfc_struct pfc_type;

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

int diseffect,a[total_instruction];

int page[total_instruction], offset[total_instruction];

void initialize(int total_pf);

void FIFO(int total_pf);

void LRU(int total_pf);

void OPT(int total_pf);

void LFU(int total_pf);

void NUR(int total_pf);

#include

#include

#include

main()

{

int S,i;

srand( (unsigned)time( NULL ) );

/* srand(getpid()*10);*/

/*由于每次运行时进程号不同,故可用来作为初始化随机数的"种子"*/

S=(float)319*rand()/32767+1;

for(i=0;i

{

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

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

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

a[i+3]=a[i+2]+1; /*执行后地址指令*/

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

}

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",i);

FIFO(i);

LRU(i);

OPT(i);

LFU(i);

NUR(i);

printf("\n");

}

return(0);

}

//void FIFO(total_pf) /*FIFO(First In First Out) ALOGRITHM*/

//int total_pf; /*用户进程的内存页面数*/

void FIFO(int total_pf)

//int total_pf;

{

int i;

pfc_type *p;

initialize(total_pf);

busypf_head=busypf_tail=NULL;

for (i=0;i

{

if (pl[page[i]].pfn==INV ALID)

{diseffect+=1;

if (freepf_head==NULL)

{

p=busypf_head->next;

pl[busypf_head->pn].pfn=INV ALID;

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);

}

void LRU(int total_pf)

//int total_pf;

{

int min,minj,i,j,present_time;

initialize(total_pf);

present_time=0;

for(i=0;i

{

if (pl[page[i]].pfn=INV ALID)

{

diseffect++;

if (freepf_head==NULL)

{

min=32767;

for(j=0;j

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

{

min=pl[j].time;

minj=j;

}

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

pl[min].pfn=INV ALID;

pl[min].time=-1;

freepf_head->next=NULL;

}

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

freepf_head=freepf_head->next;

}

else

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

present_time++;

}

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

}

void NUR(int total_pf)

//int total_pf;

{

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==INV ALID) /*页面失效*/

{

diseffect++;

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

{

cont_flag=TRUE;

old_dp=dp;

while(cont_flag)

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

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=INV ALID;

freepf_head->next=NULL;

}

《操作系统原理》信管专业实验指导书资料

《操作系统原理》实验指导书 班级:_______________ 学号:_______________ 姓名:_______________ 山东建筑大学管理工程学院 信息管理与信息系统教研室

目录 引言 (1) 实验题目一 (2) 实验题目二 (4) 实验题目三 (6) 实验题目四 (8) 实验题目五 (10) 实验题目六 (12)

引言 操作系统是信息管理与信息系统专业一门重要的专业理论课程,了解和掌握操作系统的基本概念、功能和实现原理,对认识整个计算机系统的工作原理十分重要。 操作系统实验是操作系统课程的一个重要组成部分,通过试验环节的锻炼使同学们不仅能够对以前的所学过的基础知识加以巩固,同时能够通过上机实验,对操作系统的抽象理论知识加以理解,最终达到融会贯通的目的,因此,实验环节是同学们理解、掌握操作系统基本理论的一个重要环节。 本实验指导书,根据教材中的重点内容设定了相应的实验题目,由于实验课程的学时有限,我们规定了必做题目和选做题目,其中必做题目必须在规定的上机学时中完成,必须有相应的预习报告和实验报告。选做题目是针对有能力或感兴趣的同学利用课余时间或上机学时的剩余时间完成。

实验题目一:模拟进程创建、终止、阻塞、唤醒原语 一、题目类型:必做题目。 二、实验目的:通过设计并调试创建、终止、阻塞、唤醒原语功能,有助于对操作系统中进 程控制功能的理解,掌握操作系统模块的设计方法和工作原理。 三、实验环境: 1、硬件:PC 机及其兼容机。 2、软件:Windows OS ,Turbo C 或C++、VC++、https://www.doczj.com/doc/9e4726174.html, 、Java 等。 四、实验内容: 1、设计创建、终止、阻塞、唤醒原语功能函数。 2、设计主函数,采用菜单结构(参见后面给出的流程图)。 3、设计“显示队列”函数,目的能将就绪、阻塞队列中的进程信息显示在屏幕上,以供 随时查看各队列中进程的变化情况。 五、实验要求: 1、进程PCB 中应包含以下内容: 2、系统总体结构: 其中: 进程名用P1,P2标识。 优先级及运行时间:为实验题目二做准备。 状态为:就绪、运行、阻塞,三种基本状态。 指针:指向下一个PCB 。

操作系统实验报告

操作系统实验报告 集团企业公司编码:(LL3698-KKI1269-TM2483-LUI12689-ITT289-

实验二进程调度1.目的和要求 通过这次实验,理解进程调度的过程,进一步掌握进程状态的转变、进程调度的策略,进一步体会多道程序并发执行的特点,并分析具体的调度算法的特点,掌握对系统性能的评价方法。 2.实验内容 阅读教材《计算机操作系统》第二章和第三章,掌握进程管理及调度相关概念和原理。 编写程序模拟实现进程的轮转法调度过程,模拟程序只对PCB进行相应的调度模拟操作,不需要实际程序。假设初始状态为:有n个进程处于就绪状态,有m个进程处于阻塞状态。采用轮转法进程调度算法进行调度(调度过程中,假设处于执行状态的进程不会阻塞),且每过t个时间片系统释放资源,唤醒处于阻塞队列队首的进程。 程序要求如下: 1)输出系统中进程的调度次序; 2)计算CPU利用率。 3.实验环境 Windows操作系统、VC++6.0 C语言 4设计思想: (1)程序中进程可用PCB表示,其类型描述如下:

structPCB_type { intpid;//进程名 intstate;//进程状态 2——表示“执行”状态 1——表示“就绪”状态 0——表示“阻塞”状态 intcpu_time;//运行需要的CPU时间(需运行的时间片个数) } 用PCB来模拟进程; (2)设置两个队列,将处于“就绪”状态的进程PCB挂在队列ready中;将处于“阻塞”状态的进程PCB挂在队列blocked中。队列类型描述如下: structQueueNode{ structPCB_typePCB; StructQueueNode*next; } 并设全程量: structQueueNode*ready_head=NULL,//ready队列队首指针 *ready_tail=NULL,//ready队列队尾指 针

操作系统实验实验1

广州大学学生实验报告 1、实验目的 1.1、掌握进程的概念,明确进程的含义 1.2、认识并了解并发执行的实质 2.1、掌握进程另外的创建方法 2.2、熟悉进程的睡眠、同步、撤消等进程控制方法 3.1、进一步认识并发执行的实质 3.2、分析进程竞争资源的现象,学习解决进程互斥的方法 4.1、了解守护进程 5.1、了解什么是信号 5.2、INUX系统中进程之间软中断通信的基本原理 6.1、了解什么是管道 6.2、熟悉UNIX/LINUX支持的管道通信方式 7.1、了解什么是消息 7.2、熟悉消息传送的机理 8.1、了解和熟悉共享存储机制 二、实验内容 1.1、编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统 中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示'a',子进程分别显示字符'b'和字符'c'。试观察记录屏幕上的显示结果,并分析原因。 1.2、修改上述程序,每一个进程循环显示一句话。子进程显示'daughter …'及 'son ……',父进程显示'parent ……',观察结果,分析原因。 2.1、用fork( )创建一个进程,再调用exec( )用新的程序替换该子进程的内容 2.2、利用wait( )来控制进程执行顺序 3.1、修改实验(一)中的程序2,用lockf( )来给每一个进程加锁,以实现进程之间的互斥 3.2、观察并分析出现的现象 4.1、写一个使用守护进程(daemon)的程序,来实现: 创建一个日志文件/var/log/Mydaemon.log ; 每分钟都向其中写入一个时间戳(使用time_t的格式) ; 5.1、用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按^c键);捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止: Child process1 is killed by parent! Child process2 is killed by parent! 父进程等待两个子进程终止后,输出如下的信息后终止: Parent process is killed! 5.2、用软中断通信实现进程同步的机理

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

一、实验目的 通过对进程调度算法的设计,深入理解进程调度的原理。 进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。 进程调度分配处理机,是控制协调进程对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)调度算法,时间片轮转。流程图如下:

操作系统实验_实验1

广州大学学生实验报告 开课学院及实验室:计算机科学与工程实验室 2015年11月11日 实验课 操作系统成绩 程名称 实验项 进程管理与进程通信指导老师陈康民目名称 (***报告只能为文字和图片,老师评语将添加到此处,学生请勿作答***) 进程管理 (一)进程的创建实验 一、实验目的 1、掌握进程的概念,明确进程的含义 2、认识并了解并发执行的实质 二、实验内容 1、编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统中有一 个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示'a',子进程分别显示字符'b'和字符'c'。试观察记录屏幕上的显示结果,并分析原因。 2、修改上述程序,每一个进程循环显示一句话。子进程显示'daughter …'及'son ……', 父进程显示'parent ……',观察结果,分析原因。 三、实验步骤 1、编写一段程序,使用系统调用fork( )创建两个子进程。 代码: #include main( ) { int p1,p2; while((p1=fork( ))= = -1); /*创建子进程p1*/ if (p1= =0) putchar('b'); else { while((p2=fork( ))= = -1); /*创建子进程p2*/ if(p2= =0) putchar('c'); else putchar('a'); } } 运行结果:

bca,bac, abc ,……都有可能。 2、修改上述程序,每一个进程循环显示一句话。子进程显示'daughter …'及'son ……',父进程显示'parent ……',观察结果,分析原因。 代码:#include main( ) { int p1,p2,i; while((p1=fork( ))= = -1); /*创建子进程p1*/ if (p1= =0) for(i=0;i<10;i++) printf("daughter %d\n",i); else { while((p2=fork( ))= = -1); /*创建子进程p2*/ if(p2= =0) for(i=0;i<10;i++) printf("son %d\n",i); else for(i=0;i<10;i++) printf("parent %d\n",i); } } 结果:

操作系统原理实验-系统内存使用统计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的工程,单击完成。

操作系统原理实验指导

操作系统实验指导 操作系统是计算机的最重要的系统软件,它在计算机中具有核心地位,其作用是对计算机系统资源进行统一的调度和管理,提供各种强有力的系统服务,为用户创造灵活而又方便的使用环境。一个精心设计的操作系统能极大地扩充计算机系统的功能,充分地发挥系统中各种资源的使用效率,提高系统工作的可靠性。 操作系统原理是计算机科学与技术专业的一门主要专业课程,它涉及计算机系统中各种软、硬资源管理的实现原理与方法,内容非常丰富,综合性非常强,并且还具有很强的实践性。只有把理论与实践紧密地结合起来,才能取得较好地学习效果。 培养计算机专业学生的系统程序设计能力,也是本课程的重要环节。系统程序要求结构清晰、合理、可读性好,有准确而简明的注释。通过实验可以培养学生正规系统程序设计能力。 本实验包括下列六个方面: 实验一几种操作系统的界面 实验二进程调度 实验三存储器管理 实验四存储器管理 实验五磁盘驱动调度 实验六文件管理系统 上述每个实验约需要10个学时。可根据实际情况选用。最好学生自己独立完成,如有困难,可参考一些示例,弄清每个实验的思想和实现方法,上机调试通过,不能完全照搬示例。 实验一几种操作系统的界面 1、目的与要求 目的:通过本实验,学生应熟悉1~2种操作系统的界面。在熟练使用的基础上,能了解各种命令和调用在系统中的大致工作过程,也就是通过操作系统的外部特性,逐步深入到操作系统的内在实质内容中去。 要求:能熟练地在1~2种操作系统环境下工作。学会使用各种命令,熟悉系统提供的各种功能。主动而有效地使用计算机。 熟悉系统实用程序的调用方法和各种系统调用模块的功能和用法。 2、示例 用1~2种操作系统提供的各种手段,建立、修改、编辑、编译和运行程序,最后撤消一个简单程序。要尽可能多地使用系统提供的各种命令和功能。 操作系统可为如下两种序列: (1)Windows 98或Windows 2000或Windows XP。 (2)Linux或Unix。 下面简要介绍一下Unix操作系统。 Unix是一个分时操作系统,面向用户的界面shell是一种命令程序设计语言,这种语言向用户提供了从低到高,从简单到复杂的三个层次的使用方式。它们是简单命令、组合命令和shell过程。 简单命令:Unix命令一律使用小写字母。 例如:ls -l 显示文件目录(长格式) rm 删除一个文件 cat 合并和传送文件、 cp 复制文件 mv 文件改名 cc 编译C语言源程序 组合命令:shell简单命令可以用管道算符|组合构成功能更强的命令。

操作系统实验指导_源码参考资料

华东交通大学 软件学院 操作系统实验报告 专业: 计算机科学与技术 姓名: 林庆达 学号: 3103005138 2005-6

试验一进程调度 一、实验目的: 编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。 二、实验内容:以两种典型算法为例说明实现的算法 (一)、最高优先数优先的调度算法 1、实验原理 进程调度算法:采用最高优先数优先 的调度算法(即把处理机分配给优先数最 高的进程)和先来先服务算法。 每个进程有一个进程控制块(PCB) 表示。进程控制块可以包含如下信息:进 程名、优先数、到达时间、需要运行时间、 已用CPU时间、进程状态等等。 进程的优先数及需要的运行时间可以 事先人为地指定(也可以由随机数产生)。 进程的到达时间为进程输入的时间。 进程的运行时间以时间片为单位进 行计算。 每个进程的状态可以是就绪W (Wait)、运行R(Run)、或完成F(Finish) 三种状态之一。 就绪进程获得CPU后都只能运行一 个时间片。用已占用CPU时间加1来表示。 如果运行一个时间片后,进程的已占 用CPU时间已达到所需要的运行时间, 则撤消该进程,如果运行一个时间片后进 程的已占用CPU时间还未达所需要的运 行时间,也就是进程还需要继续运行,此 时应将进程的优先数减1(即降低一级), 然后把它插入就绪队列等待CPU。 每进行一次调度程序都打印一次运 行进程、就绪队列、以及各个进程的PCB, 以便进行检查。 重复以上过程,直到所有进程都完成为止。 2、源代码: #include "stdio.h" #include #include #define getpch(type) (type*)malloc(sizeof(type)) #define NULL 0

操作系统实验一

本科实验报告 课程名称:操作系统 学号: 姓名: 专业: 班级: 指导教师: 课内实验目录及成绩 信息技术学院

实验(实验一) 1 实验名称:基本shell命令及用户管理 2 实验目的 2.1 掌握安装Linux操作系统的方法。 2.2 掌握Linux操作系统的基本配置。 2.3 了解GNOME桌面环境。 2.4 掌握基本shell命令的使用。 3 实验准备 3.1 下载VMware Workstation虚拟机软件(版本不限)。 3.2 准备Linux操作系统的安装源(内核版本和发行版本均不限)。 注:实验准备、实验内容4.1和4.2作为回家作业布置,同学们利用课余时间可在私人计算机上完成。 4 实验要求、步骤及结果 4.1 安装虚拟机软件。 【操作要求】安装VMware Workstation虚拟机软件,并填写以下4.1.1和4.1.2的内容。 4.1.1【VMware Workstation虚拟机版本号】 4.1.2【主要配置参数】 4.2 安装Linux操作系统。 【操作要求】安装Linux操作系统,版本不限。 Linux发行版本: Linux内核版本:

【主要操作步骤:包括分区情况】 1、创建一台虚拟机安装操作系统时客户机操作系统选择Linux 2、修改虚拟机的安装路径。 3、建一个新的虚拟磁盘,磁盘的空间20GB,并且将单个文件存储虚拟磁盘。 4、设置分区完毕,安装虚拟机 4.3 了解Linux操作系统的桌面环境之一GNOME。 【操作要求】查看桌面图标,查看主菜单,查看个人用户主目录等个人使用环境。【操作步骤1】桌面图标

【操作步骤2】主菜单 【操作步骤3】个人用户主目录 【操作步骤4】启动字符终端

实验指导(2015完全版)

操作系统上机实验指导书 (第一版) 闫大顺李晟编著 吴家培主审 计算机科学与工程学院 2014.8

操作系统实验指导 本课程是为《计算机操作系统》课所开的实验。计算机操作系统课程是一门实践性很强的技术课程,本课程实验的目的在于培养学生的实践能力,促进理论与实践的结合。要求学生通过上机编程,熟悉对操作系统原理,并熟练使用程序接口,并了解如何模拟操作系统原理的实现,从而加深对操作系统原理的领会,加深对操作系统实现方法的理解,与此同时使学生在程序设计方面也能够得到很大程度的提高。 实验的目的是使学生理论联系实际,提高学生系统理解与开发能力。这里所列的实验分为必做和选做。具体实验题的选择,不仅要考虑课程内容,而且要考虑学生目前的编程能力,要由浅入深。教师可通过运行示例或动画,帮助学生理解实验要求。学生应选择自己熟悉的语言与开发环境去完成实验。根据以往的教学经验,Delphi、C++ Builder,JBuilder由于提供了许多可重用的构件,易于学习、使用,VC++学习、使用困难较多。实验要求尽量在windows操作系统下,也可以在Linux下完成,由于多数没有专门学习Linux,在其平台下做试验比较困难。实验的硬件要求是能够支持VC++、Delphi、C++ Builder,JBuilder的微机即可。每个学生都独立在一台计算机上完成自己的实验内容,杜绝学生的抄袭。 实验报告的要求 1. 每位同学准备实验报告本,上机前作好充分的准备工作,预习本次实验的内容,事先熟悉与实验有关的软硬件环境。 2. 实验时遵守实验室的规章制度,爱护实验设备,对于实验设备出现的问题,要及时向指导老师汇报。 3. 提交实验文件格式:[班级][学号]_[实验题号].[扩展名] 例:计051班学号为03的学生第四个实验的文件名为:j05103_4.c 4. 最终的实验报告按照实验名称、实验目的、实验内容,实验过程(程序设计、实现与调试)、实验总结五部分书写,按时上交。实验总结是对于实验过程中出现的问题或疑惑的分析与思考。认真按照要求填写到实验报告纸上。

操作系统实验报告

操作系统实验报告 实验名称: 系统的引导 所在班级: 指导老师: 老师 实验日期: 2014年3 月29 日

一、实验目的 ◆熟悉hit-oslab实验环境; ◆建立对操作系统引导过程的深入认识; ◆掌握操作系统的基本开发过程; ◆能对操作系统代码进行简单的控制,揭开操作系统的神秘面纱。 二、实验容 1. 阅读《Linux核完全注释》的第6章引导启动程序,对计算机和Linux 0.11的引导过程进行初步的了解。 2. 按照下面的要求改写0.11的引导程序bootsect.s。 3. 有兴趣同学可以做做进入保护模式前的设置程序setup.s。 4. 修改build.c,以便可以使用make BootImage命令 5. 改写bootsect.s主要完成如下功能: bootsect.s能在屏幕上打印一段提示信息XXX is booting...,其中XXX是你给自己的操作系统起的名字,例如LZJos、Sunix等。 6. 改写setup.s主要完成如下功能: bootsect.s能完成setup.s的载入,并跳转到setup.s开始地址执行。而setup.s 向屏幕输出一行"Now we are in SETUP"。setup.s能获取至少一个基本的硬件参数(如存参数、显卡参数、硬盘参数等),将其存放在存的特定地址,并输出到屏幕上。setup.s不再加载Linux核,保持上述信息显示在屏幕上即可。 三、实验环境

本实验使用的系统是windows系统或者是Linux系统,需要的材料是osexp。 四、实验步骤 1. 修改bootsect.s中的提示信息及相关代码; 到osexp\Linux-0.11\boot目录下会看到图1所示的三个文件夹,使用UtraEdit 打开该文件。将文档中的98行的mov cx,#24修改为mov cx,#80。同时修改文档中的第246行为图2所示的情形。 图1图2 图3 2. 在目录linux-0.11\boot下,分别用命令as86 -0 -a -o bootsect.obootsect.s和 ld86 -0 -s -obootsectbootsect.o编译和bootsect.s,生成bootsect文件; 在\osexp目录下点击MinGW32.bat依此输入下面的命令: cd linux-0.11 cd boot as86 -0 -a -o bootsect.obootsect.s ld86 -0 -s -o bootsectbootsect.o

操作系统原理实验四

实验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); ﹜

操作系统实验报告

操作系统实验报告 学生学院计算机学院 专业班级计算机科学与技术3班学号3213005910 学生姓名林虹 指导教师丁国芳 2015 年12月15 日

目录 1 实验一进程调度 (1) 2 实验二银行家算法 (16) 3 实验三动态分区分配方式的模拟 (20) 4 实验四仿真各种磁盘调度算法 (26)

实验一进程调度 1. 实验目的 编写并调试一个模拟的进程调度程序,分别采用“短进程优先”、“时间片轮转”、“高响应比优先”调度算法对随机产生的五个进程进行调度,并比较算法的平均周转时间。以加深对进程的概念及进程调度算法的理解。 2. 实验要求 1.每个进程由一个进程控制块(PCB)表示,进程控制块可以包含如下信息:进程 名、优先数(响应比)、到达时间、需要运行时间(进程的长度)、已运行时间、进 程状态等等(可以根据需要自己设定)。 2.由程序自动生成进程(包括需要的数据,要注意数据的合理范围),第一个进程到 达时间从0开始,其余进程到达时间随机产生。 3.采用时间片轮转调度算法时,进程的运行时间以时间片为单位进行计算。 4.每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)三种 状态之一。 5.每进行一次调度,程序都要输出一次运行结果:正在运行的进程、就绪队列中的进 程、完成的进程以及各个进程的PCB,以便进行检查。 6.最后计算各调度算法的平均周转时间,并进行比较、分析。 3. 实验内容 a.算法原理 (1)短进程优先调度算法 “短进程优先”调度算法的基本思想是把CPU分配给就绪队列中需要时间最短的进程。 (2)时间片轮转算法 将系统中所有的就绪进程按照FCFS原则,排成一个队列。每次调度时将CPU 分派给队首进程,让其执行一个时间片。时间片的长度从几个ms到几百ms。在一个时间片结束时,发生时钟中断。调度程序据此暂停当前进程的执行,将其送到就绪队列的末尾,并通过上下文切换执行当前的队首进程。进程可以未使用完一个时间片,就出让CPU。 (3)高响应比优先算法 HRRN调度策略同时考虑每个作业的等待时间长短和估计需要的执行时间长短,从中选出响应比最高的作业投入执行。 每个作业完成后要打印该作业的开始运行时刻、完成时刻、周转时间和带权周转时间,这一组作业完成后要计算并打印这组作业的平均周转时间、带权平均周转时间。

操作系统实验报告.

学生学号0121210680225 实验课成绩 武汉理工大学 学生实验报告书 实验课程名称操作系统 开课学院计算机科学与技术学院 指导老师姓名刘军 学生姓名李安福 学生专业班级软件sy1201 2014 — 2015 学年第一学期

《操作系统》实验教学大纲 课程编号: 课程名称:操作系统/Operating System 实验总学时数:12学时 适应专业:计算机科学与技术、软件工程 承担实验室:计算机科学与技术学院实验中心 一、实验教学的目的和任务 通过实验掌握Linux系统下常用键盘命令、系统调用、SHELL编程、后台批处理和C程序开发调试手段等基本用法。 二、实验项目及学时分配 序号实验项目名称实验学时实验类型开出要求 01 Linux键盘命令和vi 2 设计必开 02 Linux下C编程 2 设计必开 03 SHELL编程和后台批处理 2 设计必开 04 Linux系统调用(time) 2 设计必开 05 Linux进程控制(fork) 4 设计必开 三、每项实验的内容和要求: 1、Linux键盘命令和vi 要求:掌握Linux系统键盘命令的使用方法。 内容:见教材p4, p9, p40, p49-53, p89, p100 2、Linux下的C编程 要求:掌握vi编辑器的使用方法;掌握Linux下C程序的源程序编辑方法;编译、连接和运行方法。 内容:设计、编辑、编译、连接以及运行一个C程序,其中包含键盘输入和屏幕输出语句。 3、SHELL编程和后台批处理 要求:掌握Linux系统的SHELL编程方法和后台批处理方法。 内容:(1) 将编译、连接以及运行上述C程序各步骤用SHELL程序批处理完成,前台运行。 (2) 将上面SHELLL程序后台运行。观察原C程序运行时输入输出情况。 (3) 修改调试上面SHELL程序和C程序,使得在后台批处理方式下,原键 盘输入内容可以键盘命令行位置参数方式交互式输入替代原键盘输入内容, 然后输出到屏幕。 4、Linux系统调用使用方法。

操作系统原理实验报告(终版)

操作系统原理实验报告(终版)

————————————————————————————————作者:————————————————————————————————日期:

[键入文字] XX学校 实验报告 课程名称: 学院: 专业班: 姓名: 学号: 指导教师: 2011 年3 月

目录 实验1 进程管理 (3) 一、实验目的 (3) 二、实验内容 (3) 三、实验要求 (3) 四、程序说明和程序流程图 (4) 五、程序代码 (5) 六、程序运行结果及分析 (7) 七.指导教师评议 (8) 实验2 进程通信 (9) 一、实验目的 (9) 二、实验内容 (9) 三、实验要求 (9) 四、程序说明和程序流程图 (9) 五、程序代码 (11) 七.指导教师评议 (14) 实验3 存储管理 (15) 一、实验目的 (15) 二、实验内容 (15) 三、实验要求 (15) 四、程序说明和程序流程图 (16) 六、程序运行结果及分析 (23)

七.指导教师评议 (23) 实验4 文件系统 (24) 一、实验目的 (24) 二、实验内容 (24) 三、实验要求 (24) 四、程序说明和程序流程图 (24) 五、程序代码 (26) 六、程序运行结果及分析 (26) 七.指导教师评议 (27)

实验1 进程管理 一、实验目的 1. 弄清进程和程序的区别,加深对进程概念的理解。 2. 了解并发进程的执行过程,进一步认识并发执行的实质。 3. 掌握解决进程互斥使用资源的方法。 二、实验内容 1. 管道通信 使用系统调用pipe( )建立一个管道,然后使用系统调用fork( )创建2个子进程p1和p2。这2个子进程分别向管道中写入字符串:“Child process p1 is sending message!”和“Child process p2 is sending message!”,而父进程则从管道中读出来自两个子进程的信息,并显示在屏幕上。 2. 软中断通信 使用系统调用fork( )创建2个子进程p1和p2,在父进程中使用系统调用signal( )捕捉来自键盘上的软中断信号SIGINT(即按Ctrl-C),当捕捉到软中断信号SIGINT后,父进程使用系统调用kill( )分别向2个子进程发出软中断信号SIGUSR1和SIGUSR2,子进程捕捉到信号后分别输出信息“Child process p1 is killed by parent!”和“Child process p2 is killed by parent!”后终止。而父进程等待2个子进程终止后,输出信息“Parent process is killed!”后终止。 三、实验要求 1. 根据实验内容编写C程序。 2. 上机调试程序。 3. 记录并分析程序运行结果。

操作系统实验报告

操作系统实验报告 银行家算法 班级:计算机()班 姓名:李君益 学号:(号) 提交日期: 指导老师: 林穗 一、设计题目 加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。 要求编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用银行家算法,有效的防止和避免死锁的发生。 二、设计要求

内容: 编制银行家算法通用程序,并检测思考题中所给状态的安全性。 要求: (1)下列状态是否安全?(三个进程共享个同类资源) 进程已分配资源数最大需求数 (状态) (状态) (2)考虑下列系统状态 分配矩阵最大需求矩阵可用资源矩阵 问系统是否安全?若安全就给出所有的安全序列。若进程请求(),可否立即分配? 三、设计分析 一.关于操作系统的死锁 .死锁的产生 计算机系统中有许多独占资源,他们在任一时刻只能被一个进程使用,如磁带机,绘图仪等独占型外围设备,或进程表,临界区等软件资源。两个进程同时向一台打印机输出将导致一片混乱,两个进程同时进入临界区将导致数据库错误乃至程序崩溃。正因为这些原因,所有操作系统都具有授权一个进程独立访问某一辞源的能力。一个进程需要使用独占型资源必须通过以下的次序: ●申请资源 ●使用资源 ●归还资源 若申请施资源不可用,则申请进程进入等待状态。对于不同的独占资源,进程等待的方式是有差别的,如申请打印机资源、临界区资源时,申请失败将一位这阻塞申请进程;而申请打开文件文件资源时,申请失败将返回一个错误码,由申请进程等待一段时间之后重试。只得指出的是,不同的操作系统对于同一种资源采取的等待方式也是有差异的。 在许多应用中,一个进程需要独占访问多个资源,而操作系统允许多个进程并发执行共享系统资源时,此时可能会出现进程永远被阻塞的现象。这种现象称为“死锁”。 2.死锁的定义 一组进程处于死锁状态是指:如果在一个进程集合中的每个进程都在等待只能由该集合中的其他一个进程才能引发的时间,则称一组进程或系统此时发生了死锁。 .死锁的防止 .死锁产生的条件: ●互斥条件

操作系统实验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时出现

操作系统原理实验五

实验五线程的同步 1、实验目的 (1)进一步掌握Windows系统环境下线程的创建与撤销。 (2)熟悉Windows系统提供的线程同步API。 (3)使用Windows系统提供的线程同步API解决实际问题。 2、实验准备知识:相关API函数介绍 ①等待对象 等待对象(wait functions)函数包括等待一个对象(WaitForSingleObject ())和等待多个对象(WaitForMultipleObject())两个API函数。 1)等待一个对象 WaitForSingleObject()用于等待一个对象。它等待的对象可以为以下对象 之一。 ·Change ontification:变化通知。 ·Console input: 控制台输入。 ·Event:事件。 ·Job:作业。 ·Mutex:互斥信号量。 ·Process:进程。 ·Semaphore:计数信号量。 ·Thread:线程。 ·Waitable timer:定时器。 原型: DWORD WaitForSingleObject( HANDLE hHandle, // 对象句柄 DWORD dwMilliseconds // 等待时间 ); 参数说明: (1)hHandle:等待对象的对象句柄。该对象句柄必须为SYNCHRONIZE访问。 (2)dwMilliseconds:等待时间,单位为ms。若该值为0,函数在测试对象的状态后立即返回,若为INFINITE,函数一直等待下去,直到接收到 一个信号将其唤醒,如表2-1所示。 返回值: 如果成功返回,其返回值说明是何种事件导致函数返回。

Static HANDLE hHandlel = NULL; DWORD dRes; dRes = WaitForSingleObject(hHandlel,10); //等待对象的句柄为hHandlel,等待时间为10ms 2)等待对个对象 WaitForMultiple()bject()在指定时间内等待多个对象,它等待的对象与 WaitForSingleObject()相同。 原型: DWORD WaitForMultipleObjects( DWORD nCount, //句柄数组中的句柄数 CONST HANDLE * lpHandles, //指向对象句柄数组的指针 BOOL fWaitAll, //等待类型 DWORD dwMilliseconds //等待时间 ); 参数说明: (1)nCount:由指针 * lpHandles指定的句柄数组中的句柄数,最大数是MAXIMUM WAIT OBJECTS。 (2)* lpHandles:指向对象句柄数组的指针。 (3)fWaitAll:等待类型。若为TRUE,当由lpHandles数组指定的所有对象被唤醒时函数返回;若为FALSE,当由lpHandles数组指定的某一个 对象被唤醒时函数返回,且由返回值说明是由于哪个对象引起的函数 返回。 (4)dwMilliseconds:等待时间,单位为ms。若该值为0,函数测试对象的状态后立即返回;若为INFINITE,函数一直等待下去,直到接收到 一个信号将其唤醒。 返回值:、 如果成功返回,其返回值说明是何种事件导致函数返回。 各参数的描述如表2-2所示。

操作系统原理课程设计

操作系统原理课程设计 ——银行家算法模拟 指导老师:周敏唐洪英杨宏雨 杨承玉傅由甲黄贤英 院系:计算机学院计算机科学与技术班级:0237-6 学号:2002370609 姓名:刘洪彬 同组者:杨志 时间:2005/1/10---2005/1/14

银行家算法模拟 一、设计目的 本课程设计是学生学习完《计算机操作系统》课程后,进行的一次全面的综合训练,通过课程设计,让学生更好地掌握操作系统的原理及实现方法,加深对操作系统基础理论和重要算法的理解,加强学生的动手能力。 二、设计要求 银行家算法是避免死锁的一种重要方法,本实验要求用高级语言编写和调试一个简单的银行家算法程序。加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。 从课程设计的目的出发,通过设计工作的各个环节,达到以下教学要求:两人一组,每组从所给题目中任选一个(如自拟题目,需经教师同意),每个学生必须独立完成课程设计,不能相互抄袭,同组者文档不能相同; 设计完成后,将所完成的工作交由老师检查; 要求写出一份详细的设计报告。 三、设计内容 编制银行家算法通用程序,并检测所给状态的系统安全性。 1)银行家算法中的数据结构 假设有n个进程m类资源,则有如下数据结构: 可利用资源向量Available。这是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态地改变。Available[j]=K,则表示系统中现有Rj 类资源K个。 最大需求矩阵Max。这是一个n*m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。 分配矩阵Allocation。这也是一个n*m的矩阵,它定义了系统中每一类资源当前已分配给没一进程的资源数。如果Allocation[i,j]=K,则表示进程i 当前已分得Rj类资源的数目为K。 需求矩阵Need。这也是一个n*m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。

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