操作系统实验报告

操作系统实验报告 

学院:计算机科学与技术学院

   班级:     电计1103    

   姓名: 

          

             

   完成日期:   2014.6.5                            

大连理工大学

Dalian University of Technology


大连理工大学实验报告

学院(系):    计算机科学与技术学院  专业:   计算机科学与技术    班级:电计1103 

姓     名:           学号:                                      

指导教师签字:                                            成绩:                  

实验一:进程控制

一、实验目的

1)掌握进程的概念,明确进程的含义  

2)认识并了解并发执行的实质

二、实验环境

1)Cygwin

2)在windows平台上

3)模拟UNIX运行环境

4)Gcc命令的使用

三、实验内容

1)作业一

 

  

Ø  getpid()---获取进程的pid

Ø  每个进程都执行自己独立的程序,打印自己的pid;

Ø  父进程打印子进程的pid;

Ø   

 2)作业二

 


Ø  getpid()---获取进程的pid

Ø  每个进程都执行自己独立的程序,打印自己的pid;

Ø  父进程打印两个子进程的pid;

Ø   

3)作业三

   写一个命令处理程序,能处理max(m,n), min(m,n),average(m,n,l)这几个命令(使用exec函数族)。

Max函数

Min函数

Average函数

Exec函数族调用(百度)

四、程序代码

1)作业一

#include<stdio.h>

#include<unistd.h>

int main()

{

    if(fork() == 0)

    {

        printf("This is son process.\n");

        printf("The son's ID is %d.\n\n",getpid());

        if(fork() == 0)

        {

            printf("This is grandson process.\n");

            printf("The grandson's ID is %d.\n\n",getpid());

        }

    }

    else

    {

         printf("This is father process.\n");

         printf("The father's ID is %d.\n\n",getpid());

    }

    return 0;

}

2)作业二

#include<stdio.h>

#include<unistd.h>

int main()

{

    if(fork() == 0)

    {

        printf("This is son1 process.\n");       

printf("The son1's ID is %d.\n\n",getpid());

    }   

else   

{

        if(fork() == 0)       

{

           

printf("This is son2 process.\n");            

printf("The son2's ID is %d.\n\n",getpid());

        }       

else       

{           

printf("This is father process.\n");           

printf("The father's ID is %d.\n\n",getpid());

        }

    }   

return 0;

}

3)作业三

#include <unistd.h>

#include <string.h>

       #include <stdio.h>

#define N 10

int main()

{

     int i;    

char cmdname[N];    

char cmdpara[N][N];   

printf("$ ");    

scanf("%s",cmdname);    

if(strcmp(cmdname,"min")==0)    

{        

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

scanf("%s",cmdpara[i]);       

execl("/home/xuxu/op_homework/min","min",cmdpara[0],cmdpara[1],NULL);

     }  

else if(strcmp(cmdname,"max")==0)    

{        

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

scanf("%s",cmdpara[i]);       

execl("/home/xuxu/op_homework/max","max",cmdpara[0],cmdpara[1],NULL);

     }

else if(strcmp(cmdname,"average")==0)

    

{

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

scanf("%s",cmdpara[i]);       

execl("/home/xuxu/op_homework/average","average",cmdpara[0],cmdpara[1],cmdpara[2],NULL);   

 }   

 else     

 printf("Command Input Error!\n");    

 return 0;

}

五、运行结果

1)作业一

2)作业二

3)作业三

六、实验分析和体会

这次实验,主要是实验在cygwin环境之下进程的相关运行过程。这让我对cygwin环境有了一些了解,但是还不是很深入,我还必须加强学习,进一步理解这类知识。尽管这个实验是三个实验中相对最简单的一个实验,但是也是由于第一次接触这些东西,在编程、设计方面都存在一定的缺陷,希望这些能够多练习进行弥补。

大连理工大学实验报告

学院(系):    计算机科学与技术学院  专业:   计算机科学与技术    班级:电计1103 

姓     名:         学号:                                    

指导教师签字:                                            成绩:                  

实验二:进程间通信

一、实验目的

Linux系统的进程通信机构 (IPC) 允许在任意进程间大批量地交换数据。本实验的目的是了解和熟悉Linux支持的消息通讯机制及信息量机制。

二、实验环境

1)虚拟机

2)在windows平台上

3)模拟UNIX运行环境

三、实验内容

编写一段程序, 使其用共享存储区来实现两个进程之间的进程通讯。进程A创建一个长度为512字节的共享内存,并显示写入该共享内存的数据;进程B将共享内存附加到自己的地址空间,并向共享内存中写入数据。

四、程序代码

#include<stdio.h>

#include<stdlib.h>

#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/shm.h>

#include<string.h>

#define Key 70

int shmid,x1;

char *addr;

char *a[ ]={"HELLO  WORLD!"};

void B()

{

      shmid=shmget(Key,512,0777);

      addr=shmat(shmid,0,0);

      memset(addr,'\0',512);

      strncpy(addr,a[0],512);

      exit(0);

}

void A()

{

      shmid=shmget(Key,512,0777|IPC_CREAT);

      addr=shmat(shmid,0,0);

      printf("get %s",addr);

      exit(0);

}

main()

{

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

             if(!x1) A();

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

             if(!x1) B();

      wait(0);

      wait(0);

}

五、运行结果

六、实验分析和体会

    这是我们组唯一一个没有在规定运行环境下进行的实验,采用的虚拟机作为实验环境。在最初做这个实验的时候,真的卡在这个实验过程上了,甚至可以说是停滞不前了。但是个人的力量是有限,一个团队的力量就完全不同了,我们重新做了分工,另外虚心向其他同学请教,最终在大家的努力下完成了这个任务。在实际的科技研究中,团队的作用也不能忽视,只有处理好自己和集体的关系,才能发挥自己的效能,更高效率的完成规定任务。

大连理工大学实验报告

学院(系):    计算机科学与技术学院  专业:   计算机科学与技术    班级:电计1103 

姓     名:        学号:                  

指导教师签字:                                            成绩:                  

实验三:存储管理

一、实验目的 

1、通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解。熟悉虚存管理的各种页面淘汰算法。  

2、通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。

二、实验环境

1)Cygwin

2)在windows平台上

3)模拟UNIX运行环境

三、实验内容

 以最佳适应为例,给出可变式分区的分配回收算法。

四、程序代码

#include<stdio.h>

#include<stdlib.h>

#define MEMSIZE 100   //内存总大小

#define ALLOW 0          //未分配

#define NOTALLOW 1  //已分配

#define ADMINJOB  0  //定义默认任务id

#define DEBUG

//#undef DEBUG

typedef struct MemStateLink{      //定义空闲分区链的数据结构

      unsigned int id;

      unsigned int firstaddr;

      unsigned int lastaddr;

      unsigned int size;

      unsigned int allow;

      unsigned int jobid;

    struct MemStateLink * pre;

      struct  MemStateLink * next;

}MemStateLink, * PtrMemLink;

typedef struct MemManager{ //定义内存管理数据结构

      PtrMemLink firstnode;

      PtrMemLink lastnode;

      unsigned  Memsize;

}MemManager ,* PtrManager;

      int idcount=0;

void Error(char * s)//错误显示函数

{

printf("%s",s);

}//Error

int Init(PtrManager manager){//初始化函数

      if((manager->firstnode = (PtrMemLink)malloc(sizeof(MemStateLink)) )== NULL)

             exit(1);

      if((manager->lastnode = (PtrMemLink)malloc(sizeof(MemStateLink)) )== NULL)

             exit(1);

      manager->Memsize = MEMSIZE;

      manager->firstnode->id = idcount;

      manager->firstnode->firstaddr = 0;

      manager->firstnode->lastaddr = MEMSIZE -1;

      manager->firstnode->size = (manager->firstnode->lastaddr - manager->firstnode->firstaddr +1);

      manager->firstnode->allow = ALLOW;

      manager->firstnode->jobid = ADMINJOB;

      manager->firstnode->pre = NULL;

      manager->firstnode->next = manager->lastnode;

      manager->Memsize = MEMSIZE;

      manager->lastnode->id = idcount;

      manager->lastnode->firstaddr = 0;

      manager->lastnode->lastaddr = MEMSIZE -1;

      manager->lastnode->size = (manager->lastnode->lastaddr - manager->lastnode->firstaddr +1);

      manager->lastnode->allow = NOTALLOW;       //为避免回收内存,合并时出错,默认设置最后一块不可用

      manager->lastnode->jobid = ADMINJOB;

      manager->lastnode->pre = manager->firstnode;

      manager->lastnode->next =NULL;

      return 1;

}//init

int PrintLink(MemManager manager){//打印链表中数据

      PtrMemLink temptr;

      temptr = manager.firstnode;

      printf("id      firstad    lastad     size job  allow\n");

      while(temptr->next != NULL)

      {

             printf("%u    %u  %u  %u  %u  %u\n",temptr->id,temptr->firstaddr,temptr->lastaddr,temptr->size,temptr->jobid,temptr->allow);

             temptr = temptr->next;

      }

      return 1;

}//PrintLink

int Allocmem(PtrManager manager , unsigned int jobid , unsigned int needsize){//内存分配函数

      PtrMemLink temptr;

      PtrMemLink othermem;

      PtrMemLink minptr = NULL; //记录最小差距的内存块的指针

      int mindis = MEMSIZE;   //需要内存与空闲内存之差,最适分配算法,最好情况就是找到刚好合适的空闲内存,即mindis=0

      int temdis = 0;                          //当前的差距值

      temptr = manager->firstnode;

      #ifdef DEBUG

      printf("allocate memory %d\n",needsize);

      #endif

      while(temptr->next != NULL)

      {

             if(temptr->allow == ALLOW)

             {

             temdis = temptr->size - needsize;

             if( temdis>=0 && temdis < mindis)

                    {

                    mindis = temdis;

                    minptr = temptr;

                    }

             }

             temptr = temptr->next;

      }

      if(mindis==MEMSIZE)

      {

      #ifdef DEBUG

             printf("there is no fit node\n");

      #endif

             return 0;

      }

      else

      {//生成新的节点,并加入状态链中

             #ifdef DEBUG

             printf("The best fit memcolck is : %d\n",minptr->size);

             #endif

             if( (othermem = (PtrMemLink)malloc(sizeof(MemStateLink) ) ) == NULL)

                    exit(1);

             othermem->size = minptr->size-needsize;

             othermem->lastaddr = minptr->lastaddr;

             minptr->size = needsize;

             minptr->lastaddr = minptr->firstaddr + needsize -1;

             minptr->allow = NOTALLOW;

             minptr->jobid = jobid;

             othermem->next = minptr->next;

             othermem->pre = minptr;

             minptr->next->pre = othermem;

             minptr->next = othermem;

             othermem->allow = ALLOW;

             othermem->firstaddr = minptr->lastaddr+1;

             othermem->id = ++idcount;

             othermem->jobid = ADMINJOB;

      }

      return 1;

}//allocmem

PtrMemLink MergeAfter( PtrMemLink aimptr)//与后一个节点合并

{

             PtrMemLink nextptr;               //临时存放y要回收指针

             nextptr = aimptr->next;

             aimptr->allow = ALLOW;

             aimptr->jobid = ADMINJOB;

             aimptr->lastaddr = aimptr->next->lastaddr;

             aimptr->size += aimptr->next->size;

             aimptr->next->next->pre = aimptr;

             aimptr->next = aimptr->next->next;

             free(nextptr);

             return aimptr;

}//MergeAfter

PtrMemLink MergePre( PtrMemLink aimptr)//与前一个节点合并

{

             aimptr->pre->lastaddr = aimptr->lastaddr;

             aimptr->pre->size += aimptr->size;

             aimptr->pre->next = aimptr->next;

             aimptr->next->pre = aimptr->pre;

             free(aimptr);

             return aimptr->pre;

}//MergePre

int Recymem(PtrManager manager,unsigned int jobid){//内存回收函数

      PtrMemLink temptr;

      PtrMemLink nextptr;               //临时存放y要回收指针

      PtrMemLink aimptr = NULL; //所要回收内存块的指针

      temptr = manager->firstnode;

             while(temptr->next != NULL)

      {

             if(temptr->jobid == jobid)

             {

             aimptr = temptr;

             break;

             }

             temptr = temptr->next;

      }

      if(aimptr==NULL)

             return 0;

      #ifdef DEBUG

             printf("find it\n");

      #endif

      if(aimptr->pre == NULL && aimptr->next->next == NULL)//只有一个头节点

      {

             aimptr->allow = ALLOW;

             aimptr->jobid = ADMINJOB;

             //return 1;

      }

      else if(aimptr->pre == NULL && aimptr->next->next != NULL)//操作头结点,头节点之后还有节点

      {

             if(aimptr->next->allow == ALLOW)

                    MergeAfter(aimptr);

             else

                    {

                    aimptr->allow = ALLOW;

                    aimptr->jobid = ADMINJOB;

                    }

      }

      else if(aimptr->pre != NULL && aimptr->next->next == NULL)//操作中间节点,后面是尾节点

      {

             if(aimptr->pre->allow == ALLOW)

                    MergePre(aimptr);

             else

             {

                    aimptr->allow = ALLOW;

                    aimptr->jobid = ADMINJOB;

             }

      }

      else if(aimptr->pre != NULL && aimptr->next->next !=NULL )//操作中间节点,前非头,后非尾

      {

      if(aimptr->pre->allow == ALLOW && aimptr->next->allow == ALLOW)//上下都合并

      {

                    MergePre(MergeAfter(aimptr));

      }

      else if(aimptr->pre->allow == ALLOW && aimptr->next->allow == NOTALLOW)//与前一个合并

      {

             MergePre(aimptr);

      }

      else if(aimptr->pre->allow == NOTALLOW && aimptr->next->allow == ALLOW)//与后一个合并

      {

             MergeAfter(aimptr);

      }

      else if(aimptr->pre->allow == NOTALLOW && aimptr->next->allow == NOTALLOW)//都不合并

      {

             aimptr->allow = ALLOW;

             aimptr->jobid = ADMINJOB;

      }

      }

      else

      {

             Error("错误,不能确定节点前后情况\n");

             return 0;

      }

      return 1;

}//Recymem

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

{

      MemManager manager;    //定义内存管理变量

    int runFlag = 1;

    int order,jobId,memorySize;

      #ifdef DEBUG

             printf("define over\n");

      #endif

      Init(&manager);         //初始化

      #ifdef DEBUG

             printf("init over\n");

      #endif

      PrintLink(manager);   //打印内存情况

      #ifdef DEBUG

             printf("print over\n");

      #endif

    while(runFlag){

        printf("please input order:\n");

        printf("1:Memory Allocation.\n");

        printf("2:Memory Collection.\n");

        printf("3:EXIT.\n");

        scanf("%d",&order);

        getchar();

        switch(order){

            case 1:

                printf("Please input the job id and memory size to allocation.\n");

                scanf("%d%d",&jobId,&memorySize);

                getchar();

                printf("\n\n");

                Allocmem(&manager,jobId,memorySize);

                PrintLink(manager);

                printf("\n\n");

                break;

            case 2:

                printf("Please input the job id which is to be collected.\n");

                scanf("%d",&jobId);

                getchar();

                printf("\n\n");

                Recymem(&manager,jobId);

                PrintLink(manager);

                printf("\n\n");

                break;

            case 3:

                exit(0);

                break;

        }

    }

      return 0;

}

五、运行结果

六、实验分析和体会

分配回收算法实际早在理论课上就曾学过过,当时仅仅局限于理论理解,没有进行上机模拟,所以理解比较肤浅,故实验前着重熟悉了各种方式的原理和实现方式。所谓“谋定而后动”,上机实践还是遵循着程序设计=数据结构+算法的原则,成熟的算法和理想的数据结构可以使程序设计事半功倍。这是操作系统的最后一个实验,也是题目字数最少但是代码行数最多的一个实验,通过实践操作既加深了对于分配回收的深刻理解,又熟悉掌握了常用数据结构的用法。尽管调试代码,发现bug非常煎熬(熬夜到半夜才修复所有Bug),但是最后圆满解决问题的成就感也是无与伦比的。

相关推荐