操作系统实验报告

 

实验名称

Linux 进程创建

专业

软件工程

姓名

 

学号

 

班级

 

  • 实验目的:

 

加深对进程概念的理解

练习使用fork()系统调用创建进程

练习Linux操作系统下C程序设计

 

二、实验内容:

使用fork()调用计算Fibonacci数列

Fibonacci数列是0,1,1,2,3,5,8…….通常表示为:fib0=0,fib1=1,fibn=fibn-1+fibn-2

写一个C程序,使用fork()系统调用产生一个子进程来计算Fibonacci数列,序列通过命令行显示。例如,如果参数为5,Fibonacci数列的前5个数字将在子进程中被输出。

因为父进程和子进程拥有各自的数据拷贝,所以需要由子进程输出。在退出程序之前,父进程调用wait()等待子进程完成。

要求提供必要的错误检测以保证在命令行传递的参数是非负数。

 

三、实验设备及软件环境:

硬件:计算机

操作系统:Linux

软件环境:word

 

  • 实验过程及结果:
  1. 根据PPT自学Linux系统
  2. 学习Linux系统中的函数调用

1. fork()函数:创建一个新进程.

调用格式:

#include

#include

int fork();

返回值:

正确返回时,等于0表示创建子进程,从子进程返回的ID值;大于0表示从父进程返回的子进程的进程ID值。

错误返回时,等于-1表示创建失败

2. wait()函数:用来控制父进程与子进程的同步。在父进程中调用wait()函数,则父进程被阻塞,进入等待队列,等待子进程结束。当子进程结束时,会产生一个终止状态字,系统会向父进程发出SIGCHLD信号。当接到信号后,父进程提取子进程的终止状态字,从wait()函数返回继续执行原程序。

调用格式:

#include

#include

(pid_t) wait(int *statloc);

返回值:正确返回时大于0表示子进程的进程ID值;等于0表示其他。错误返回时等于-1表示调用失败。

3. exit()函数:进程结束最长调用的函数,在main()函数中调用return,最终也是调用exit()函数。这些都是进程的正常终止。在正常终止时,exit()函数返回进程结束状态。

调用格式:

#include

void exit(int status);

其中,status为进程结束状态。

 

 

3.尝试编写斐波那契数列

 

 

  1. 实验截图

实验代码:

#include

#include

#include

#include

int main(int argc,char* argv[])

{

pid_t pid;

int i;

int f0,f1,f2;

f0=0;

f1=1;

if(argv[1]<0)

{

fprintf(stderr,"requeest a nun-negative number");

}

pid=fork();

if(pid<0)

{

fprintf(stderr,"failed");

exit(-1);

}

else if(pid==0)

{

printf("argv[1]=%d\n",atoi(argv[1]));

printf("01");

for(i=2;i<=atoi(argv[1])-1;i++)

{

f2=f0+f1;

f0=f1;

f1=f2;

  printf("%d",f2);

}

printf("\nchild process competed\n");

}

else

{

wait(NULL);

printf("parent process exist\n");

}

return 0;

}

 

五、总结(实验结果分析,个人体会等)

这一次的上机实验,是我本人第一次接触LINUX操作系统,新鲜的事务,更让我觉得以后学习道路上更是需要十分的努力,通过这次试验,我学会了Linux的使用,并且成功的掌握了Linux操作系统的基本命令,VI的使用方法,GCC的使用方法以及调试器GDB的使用方法。在老师和同学的帮助下,我进一步学会了在Linux系统中如何创建一个目录,并在该目录下创建文件,并实现文件的目录转移。复制以及粘贴。

操作系统的学习,更不是局限在书本纸面上的内容,是需要结合实地实践和动手动脑学习的一项内容,所以以后的我会多与老师交流,参与实践,更努力学习操作系统。

实验成绩:        指导教师:       年   月    日

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

实验名称

实验二 Linux 进程通信

专业

软件工程

姓名

 

学号

 

班级

 

一、实验目的:

 

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

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

分析进程争用资源的现象,学习解决进程互斥的方法

了解Linux系统中进程通信的基本原理

掌握Linux系统软中断通信的实现方法

学会使用Linux系统中关于进程通信的实现方法

**掌握管道通信的使用

 

  • 实验内容:

 

        编制实现软中断通信的程序

使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉定时器报警中断信号(SIGALRM),当父进程接收到该信号后,调用kill()向两个子进程发送终止信号,子进程分别输出下列信息后终止。

    Child process 1 is killed by parent!!

    Child process 2 is killed by parent!!

父进程调用wait()函数等待两个子进程终止后,输出以下信息后终止。

    Parent process is killed!!

多运行几次编写的程序,简略分析出现不同结果的原因

 

  • 实验设备及软件环境:

 

硬件:计算机

操作系统:Linux

软件环境:word

 

四、实验过程及结果:

实验过程:

1. fork()函数:创建一个新进程.

    1. 调用格式:

#include

#include

int fork();

    1. 返回值:

正确返回时,等于0表示创建子进程,从子进程返回的ID值;大于0表示从父进程返回的子进程的进程ID值。

错误返回时,等于-1表示创建失败

2. wait()函数:用来控制父进程与子进程的同步。

   在父进程中调用wait()函数,则父进程被阻塞,进入等待队列,等待子进程结束。当子进程结束时,会产生一个终止状态字,系统会向父进程发出SIGCHLD信号。当接到信号后,父进程提取子进程的终止状态字,从wait()函数返回继续执行原程序。

调用格式:

#include

#include

(pid_t) wait(int *statloc);

返回值:正确返回时大于0表示子进程的进程ID值;等于0表示其他。错误返回时等于-1表示调用失败。

3. exit()函数:进程结束最长调用的函数。在main()函数中调用return,最终也是调用exit()函数。这些都是进程的正常终止。在正常终止时,exit()函数返回进程结束状态。

    1. 调用格式:

#include

void exit(int status);

其中,status为进程结束状态。

4. kill()函数:用于删除执行中的程序或者任务。

    1. 调用格式:

#include

kill(int PID, int IID);

其中,PID是要被杀死的进程号,IID为向将被杀死的进程发送的中断号。

5. signal()函数:允许调用进程控制软中断信号的处理。

    1. 调用格式:

#include

int sig;

void (*func)();

signal(sig, function);

function:在该进程中的一个函数地址,在核心返回用户态时,它以软件中断信号的序号作为参数调用该函数。

 sig的值是下列之一:

6. pipe()函数:用于创建一个管道

    1. 调用格式:

#include

pipe(int fp[2]);

其中,fp[2]是进程使用的文件描述符数组,fp[0]用于写,fp[1]用于读。

    1. 返回值:正确返回时,0表示调用成功

错误返回时,-1表示调用失败

 

实验代码:

#include

#include

#include

#include

#include

#include

 

int flag_wait=1;

 

void stop2()

{   

    flag_wait=0;

    printf("\nson interruption\n");

}

void stop()

{

    printf("\ninterruption\n");

}

 

int main()

{

    pid_t pid1,pid2;

    signal(3,stop);

 

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

    if(pid1>0)

    {

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

        if(pid2>0)

        {

            sleep(5);

            kill(pid1,16);

            wait(0);

            kill(pid2,17);

            wait(0);

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

            exit(0);

        }

        else

        {

            signal(17,stop2);

            while(flag_wait);

            printf("\nchild process 2 is killed\n");

            exit(0);

        }

    }

    else

    {

        signal(16,stop2);

        while(flag_wait);

        printf("\nchild process 1 is killed\n");

        exit(0);

    }

    return 0;

}

实验截图:

 

 

 

五、总结(实验结果分析,个人体会等)

这一次的实验,在实验1的基础上,我可以熟悉并且顺利打开linux操作系统,按照实验目的和要求进行实验2,完成进程间的通信,第二次的实验让我更体会到了面对每一次的实验内容,或者以后的实践学习过程中,都会有不同的问题和困难随之出现,我们必须要创新思维,不要固步自封的守住当前已学会的知识,而是应该针对具体情况具体分析,就像这一次的实验过程中,出现了我的命名方式总是找不到路径和地址,最后在同学的帮助下,我成功的解决了问题,让我在操作系统的学习之路上获得了小小的经验。

 

 

 

 

 

 

 

 

 

 

实验成绩:         指导教师:       年    月    日

实验名称

实验3 Linux 存储器管理

——LRU算法

专业

软件工程

姓名

 

学号

 

班级

 

一、实验目的:

进一步掌握虚拟存储器的实现方法

掌握各种页面置换算法

比较各种页面置换算法的优缺点

 

二、实验内容:

使用常量total_instruction记录页面总共使用次数,使用变量diseffect记录总

共换入页面的次数(需要换出页面,总是因为没有命中而产生)

(1)初始化。设置两个数组page[ap]和pagecontrol[pp]分别表示进程页面数和内存分配的页面数,并产生一个随机序列main[total_instruction],(当然这个序列由page[]的下标随机组成),表示待处理的进程页面顺序,diseffect置零。

(2)看main[]中是否有下一个元素。若有,则由main[]中获取该页面下标,并转到(3);若没有,则转到(6)。

(3)如果该page[]单元在内存中便改变页面属性,使它保留最近页面的信息,就转到(2);否则转到(4),同时未命中的diseffect加1。

(4)判断是否有空闲的内存页面,如果有,就返回页面指针,转到(5);否则在内存页面中找出最长时间没有使用到的页面,将其“清干净”,并返回该页面指针。

(5)将需处理的page[]与(4)中得到的pagecontrol[]建立关系,同时需让对应的page[]单元保存“最新使用”信息,返回(2)。

(6)如果序列处理完成,就输出1-diseffect/total_instruction*100%,并结束。

 

三、实验设备及软件环境:

硬件:计算机

操作系统:Linux

软件环境:word

 

四、实验过程及结果:

实验代码:

#include

#define M 4

#define N 17

#define Myprintf printf("|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|\n")      /*表格控制*/

typedef struct page

{

       int num;  /*记录页面号*/

       int time;   /*记录调入内存时间*/

}Page;                   /* 页面逻辑结构,结构为方便算法实现设计*/

 

Page b[M];            /*内存单元数*/

int c[M][N];   /*暂保存内存当前的状态:缓冲区*/

int queue[100];       /*记录调入队列*/

int K;             /*调入队列计数变量*/

 

/*初始化内存单元、缓冲区*/

void Init(Page *b,int c[M][N])

{

       int i,j;

       for(i=0;i

       {

              b[i].num=-1;

              b[i].time=N-i-1;

       }

       for(i=0;i

              for(j=0;j

                     c[i][j]=-1;

}

 

/*取得在内存中停留最久的页面,默认状态下为最早调入的页面*/

int GetMax(Page *b)

{

       int i;

       int max=-1;

       int tag=0;

       for(i=0;i

       {

              if(b[i].time>max)

              {

                     max=b[i].time;

                     tag=i;

              }

       }

       return tag;

}

 

/*判断页面是否已在内存中*/

int    Equation(int fold,Page *b)

{

       int i;

       for(i=0;i

       {

              if (fold==b[i].num)

                     return i;

       }

       return -1;

}

/*LRU核心部分*/

void Lru(int fold,Page *b)

{

       int i;

       int val;

       val=Equation(fold,b);

       if (val>=0)

       {

              b[val].time=0;

              for(i=0;i

                     if (i!=val)

                            b[i].time++;

       }

       else

       {

              queue[++K]=fold;/*记录调入页面*/

              val=GetMax(b);

              b[val].num=fold;

              b[val].time=0;

              for(i=0;i

                     if (i!=val)

                            b[i].time++;

       }

}

 

/*主程序*/

int main()

{

       int a[N]={1,0,1,0,2,4,1,0,0,8,7,5,4,3,2,3,4};

       int i,j;

 

start:

       K=-1;

       Init(b, c);

       for(i=0;i

       {

              Lru(a[i],b);

              c[0][i]=a[i];

              /*记录当前的内存单元中的页面*/

              for(j=0;j

                     c[j][i]=b[j].num;

       }

       /*结果输出*/

       printf("内存状态为:\n");

       Myprintf;

       for(j=0;j

              printf("|%2d ",a[j]);

       printf("|\n");

       Myprintf;

       for(i=0;i

       {     for(j=0;j

              {

              if(c[i][j]==-1)

                     printf("|%2c ",32);

              else

                     printf("|%2d ",c[i][j]);

              }

              printf("|\n");

       }

       Myprintf;

       printf("\n调入队列为:");

       for(i=0;i

              printf("%3d",queue[i]);

       printf("\n缺页次数为:%6d\n缺页率:%16.6f",K+1,(float)(K+1)/N);

       printf("\nAre you continuing!\ty?");

       if(getchar()=='y')

              goto start;

           return 0;

}

实验截图:

 

 

五、总结(实验结果分析,个人体会等)

这一次的实验,在两次实验的基础上,我进一步掌握了虚拟存储器的实现方法,又一次

熟悉了LINUX的环境,让我恍然大悟,学习的进步在于一遍一遍的重复与熟悉,在经验的积累基础上,然后寻求知识的掌握和升华,这一次实验内容中,我重点掌握了各种页面置换算法,着重的实现了LRU页面置换算法,比书本知识学习的更有画面感和印象感,而且通过这次试验,能够比较各种页面置换算法的优缺点,将操作系统中所学习的知识真正的做到学以致用,用于实践过程中的各个适合的场合。

 

 

实验成绩:        指导教师:       年   月    日

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

实验名称

Linux文件管理

专  业

软件工程

姓    名   

 

学  号

 

班  级

 

 

  • 实验目的:

掌握Linux文件系统的基本原理、结构和实现方法

掌握Linux文件系统中文件的建立、打开、读/写、执行、属性等系统调用的使用

学会设计简单的文件系统并实现一组操作

通过实验学习文件系统的系统调用命令,提高对文件系统实现功能的理解和掌握

  • 实验内容:

设计并实现一个一级文件系统程序,要求实现以下功能:

1. 提供文件创建/删除接口命令create/delete、目录创建/删除接口命令mkdir/rmdir、显示目录内容命令ls等。

2. 创建的文件不要求格式和内容。

三、实验设备及软件环境:

操作系统:windows XP

软件环境:VM虚拟机

四、实验过程及结果:

实验代码:

main.cpp

#include

#include

#include

#include

#include "structure.h"

#include "creat.h"

#include "access.h"

#include "ballfre.h"

#include "close.h"

#include "delete.h"

#include "dir.h"

#include "format.h"

#include "halt.h"

#include "iallfre.h"

#include "install.h"

#include "log.h"

#include "name.h"

#include "open.h"

#include "rdwt.h"

#include "igetput.h"

struct hinode hinode[NHINO];

struct dir dir;

struct file sys_ofile[SYSOPENFILE];

struct filsys filsys;

struct pwd pwd[PWDNUM];

struct user user[USERNUM];

FILE *fd;

struct inode *cur_path_inode;

int user_id;

/*kkkkk*/

unsigned short usr_id;

char usr_p[12];

char sel;

char temp_dir[12];

main()

{

unsigned short ab_fd1,ab_fd2,ab_fd3,ab_fd4,i,j;

char *buf;

    int done=1;

 

printf("\nDo you want to format the disk(y or n)?\n");

if(getchar()=='y')

    {

      printf("\nFormat will erase all context on the disk \n");

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

  format();

      printf("\nNow will install the fillsystem,please wait...\n");

  install();

      printf("\n----Login----\nPlease input your userid:");

      scanf("%u",&usr_id);

      printf("\nPlease input your password:");

      scanf("%s",&usr_p);

      /*  printf("\nsuccess\n");*/

  if(!login(usr_id,usr_p))

     return;

      while(done)

      {

         printf("\n Please Select Your Operating\n");

         printf(" -1----ls\n -2----mkdir\n -3----change dir\n -4----create file\n -0----Logout\n");/* зЂвт*/

     sel=getchar();

         sel=getchar();

     switch(sel)

     {

     case '1':

          _dir();

          break;

         case '2':

          printf("please input dir name:");

          scanf("%s",temp_dir);

          mkdir(temp_dir);

          break;

         case '3':

          printf("please input dir name:");

          scanf("%s",temp_dir);

          chdir(temp_dir);

          break;

     case '4':

          printf("please input file name:");

          scanf("%s",temp_dir);

          ab_fd1=creat(2118,temp_dir,01777);

          buf=(char *)malloc(BLOCKSIZ*6+5);

          write(ab_fd1,buf,BLOCKSIZ*6+5);

          close(0,ab_fd1);

          free(buf);

             break;

         case '0':

          logout(usr_id);

          halt();

          done = 0;

         default:

             printf("error!\nNo such command,please try again.\nOr you can ask your teacher for help.\n");

             break;

         }

     }

  }

  else

  printf("User canseled\nGood Bye\n");

}

1.4源码二(或命令)

//create.h

creat(uid,filename,mode)

unsigned int uid;

char *filename;

unsigned short mode;

{

int di_ith,di_ino;

struct inode *inode;

int i,j;

 

i=0;

while(i

{

if(user[i].u_uid==uid)

{

user_id=i;

break;

}

i++;

}

if(i==USERNUM)

{

printf("the user id is wrong.\n");

exit(1);

}

 

di_ino=namei(filename);

 

if(di_ino!=-1)//文件已经存在

{

inode=iget(di_ino);

if(access(user_id,inode,mode)==0)

{

iput(inode);

printf("\ncreat access not allowed\n");

return 0;

}

for(i=0;idi_size/BLOCKSIZ+1;i++)

{

bfree(inode->di_addr[i]);

}

for(i=0;i

if(sys_ofile[i].f_inode==inode)

{

sys_ofile[i].f_off=0;

}

for(i=0;i

if(user[user_id].u_ofile[i]==SYSOPENFILE+1)

{

user[user_id].u_uid=inode->di_uid;

user[user_id].u_gid=inode->di_gid;

for(j=0;j

if(sys_ofile[j].f_count==0)

{

user[user_id].u_ofile[i]=j;

sys_ofile[j].f_flag=(char)mode;

}

return i;

}

}

else

{

inode=ialloc();

di_ith=iname(filename);

 

dir.size++;

 

dir.direct[di_ith].d_ino=inode->i_ino;

inode->di_mode=user[user_id].u_default_mode;

inode->di_uid=user[user_id].u_uid;

inode->di_gid=user[user_id].u_gid;

inode->di_size=0;

inode->di_number=0;

 

for(i=0;i

if(sys_ofile[i].f_count==0)

{

break;

}

for(j=0;j

if(user[user_id].u_ofile[j]==SYSOPENFILE+1)

{

break;

}

 

user[user_id].u_ofile[j]=i;

sys_ofile[i].f_flag=(char)mode;

sys_ofile[i].f_count=0;

sys_ofile[i].f_off=0;

sys_ofile[i].f_inode=inode;

return j;

}

return 0;

}

1.5源码三(或命令)

//delete.h

#include

#include "structure.h"

 

delete(char *filename)

{

unsigned int dinodeid;

struct inode *inode;

 

dinodeid=namei(filename);

if(dinodeid!=(int)NULL)

inode=iget(dinodeid);

inode->di_number--;

iput(inode);

}

1.6源码四(或命令)

//dir.h

_dir()

{

unsigned int di_mode;

int i,j,one;

struct inode *temp_inode;

 

printf("CURRENT DIRECTORY:\n");

for(i=0;i

{

if(dir.direct[i].d_ino!=DIEMPTY)

{

printf("%sDIRSIZ",dir.direct[i].d_name);

temp_inode=iget(dir.direct[i].d_ino);

di_mode=temp_inode->di_mode;

for(j=0;j<9;j++)

{

one=di_mode%2;

di_mode=di_mode/2;

 

if(one) printf("x");

else printf("-");

}

if(temp_inode->di_mode&&DIFILE==1)

{

printf("%ld\n",temp_inode->di_size);

printf("block chain:");

for(i=0;idi_size/BLOCKSIZ+1;i++)

printf("%4d",temp_inode->di_addr[i]);

printf("\n");

}

else printf("

\n");

iput(temp_inode);

}

}

}

 

mkdir(char *dirname)

{

int dirid,dirpos;

struct inode *inode;

struct direct buf[BLOCKSIZ/(DIRSIZ+2)];

unsigned int block;

 

 

dirid=namei(dirname);

if(dirid!=-1)//dirid==-1表示没有该目录名存在;

{

inode=iget(dirid);

if(inode->di_mode&DIDIR)

printf("\n%s directory already existed!!\n");

else

printf("\n%s is a file name&can not creat a dir the same name",dirname);

iput(inode);

return 0;

}

 

dirpos=iname(dirname);

inode=ialloc();

inode->i_ino=dirpos;

dir.direct[dirpos].d_ino=inode->i_ino;

dir.size++;

 

strcpy(buf[0].d_name,".");

buf[0].d_ino=dirid;

strcpy(buf[1].d_name,"..");

buf[1].d_ino=cur_path_inode->i_ino;

 

block=balloc();

fseek(fd,DATASTART+block*BLOCKSIZ,SEEK_SET);

fwrite(buf,1,BLOCKSIZ,fd);

 

inode->di_size=2*(DIRSIZ+2);

inode->di_number=1;

inode->di_mode=user[user_id].u_default_mode;

 

inode->di_uid=user[user_id].u_uid;

inode->di_gid=user[user_id].u_gid;

inode->di_addr[0]=block;

 

iput(inode);

return 0;

}

 

chdir(char *dirname)

{

int dirid;

int temp;

struct inode *inode;

short block;

int i,j,low=0,high=0;

dirid=namei(dirname);

if(dirid==-1)

{

printf("\n%s does not existed\n",dirname);

return 0;

}

inode=iget(dirid);

if(!access(user_id,inode,user[user_id].u_default_mode))

{

printf("\nhas not access to the directory %s",dirname);

iput(inode);

return 0;

}

 

for(i=0;i

{

for(j=0;j

{

temp=dir.direct[j].d_ino;

 

if(dir.direct[j].d_ino==0||dir.direct[j].d_ino>MAX) break;

}

dir.direct[j].d_ino=0;

}

 

for(i=0;idi_size/BLOCKSIZ+1;i++)

{

bfree(cur_path_inode->di_addr[i]);

}

i=dir.size;

for(i=0;i

{

block=balloc();

cur_path_inode->di_addr[i]=block;

fseek(fd,DATASTART+block*BLOCKSIZ,SEEK_SET);

fwrite(&dir.direct[i],1,BLOCKSIZ,fd);

}

cur_path_inode->di_size=dir.size*(DIRSIZ+2);

iput(cur_path_inode);

 

cur_path_inode=inode;

 

i=inode->di_size/BLOCKSIZ+1;

j=0;

for(i=0;idi_size/BLOCKSIZ+1;i++)

{

fseek(fd,DATASTART+inode->di_addr[i]*BLOCKSIZ,SEEK_SET);

fread(&dir.direct[j],1,BLOCKSIZ,fd);

j+=BLOCKSIZ/(DIRSIZ+2);

}

return 0;

}

实验结果:

五、总结  

这一次,是操作系统的最后一次实验了,通过这次实验课我对操作系统的喜好更深刻一步,在前三次的基础上我掌握了Linux文件系统的基本原理、结构和实现方法,并且掌握了Linux文件系统中文件的建立、打开、读/写、执行、属性等系统调用的使用,学会设计简单的文件系统并实现一组操作。虽然实验部分的学习结束了,但是我深知自己学习操作系统的道路还没有停止,我会更加努力,知识结合实践,完成更好的成绩。

 

实验成绩:    指导教师:    年  月   日

 

 

你可能感兴趣的:(操作系统实验报告)