zoukankan      html  css  js  c++  java
  • 12.14 操作系统实验:linux虚拟机与进程管理

    实验一:熟悉Linux基础命令及进程管理

    1. 实验目的
    • 了解linux虚拟机的用途及 基本使用步骤
    • 了解进程调度的目的及应用场景
    • 加深对进程概念的理解,明确进程和程序的区别。
    • 分析进程争用资源的现象,学习解决进程互斥的方法。
    1. 实验内容
      1. 使用文件相关的linux的基础命令
      2. 运行进程处理的代码段,并解释结果
      3. 对于给定的进程处理问题,可以自行设计解决方案并代码实现
    2. 代码及运行结果分析

    1.linux基础文件命令使用

    • 创建目录/文件夹:mkdri 目录名

    • 文件重命名或移动位置:mv

      移动

      重命名

    • 删除文件或目录 rm ,rm -rf

      文件

      目录

    • 查看文件的全部内容: cat 文件路径

    • 查看文件内容:more 文件路径

    • 查看文件开头的n行数据: head -n 数字

    • 显示文件尾部的n行数据 tail -n 数字

    • 复制文件命令cp ,cp -rf

    • 在目录下查找,搜索文件:find

    2.进程管理

    • 代码修正及结果分析

    代码1

    /*test1*/
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    int main()
    {int i,j,id;
    if (i=fork())
    {
    j=wait(0);
    id=getpid();
        printf("Parent Process!
    ");
        printf("i=%d,j=%d,id=%d
    ",i,j,id);
    }
    else 
    {   
        id=getpid();
        printf("Child Process!
    ");
        printf("i=%d,id=%d
    
    ",i,id);
    }
    }

    结果

    分析

    在i=fork( ) 处创建子进程分支,父进程fork( )返回子进程id,然后进入堵塞队列,等待子进程变成zombie进程。

    子进程fork( )返回0,然后等待父进程被堵塞,子进程进入运行队列,知道运行结束变成zombie进程。

    进程树

     

    代码2

    /*test2*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    int main()
    {
        int p1,p2;
        while((p1=fork())==-1);
        if(p1==0)       
            printf("b.My process ID is %d
    ",getpid());
        else
        {
            while((p2=fork())==-1); 
            if(p2==0)               
                printf("c.My process ID is %d
    ",getpid());
            else 
                printf("a.My process ID is %d
    ",getpid());
        }
    }

    结果

    分析

    a进程在while((p1=fork())==-1)产生子进程b,在while((p2=fork())==-1)产生子进程c

    对于子进程b,p1==0,进入第一个分支,运行输出语句。

    a进入第二个分支后产生子进程c,对于子进程c,p2==0,进入第二个分支。

    a,b,c的运行顺序与运行的调度算法有关。

    进程树

     

    代码3

    /*test3*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    int main()
    {
        int m,n,k;
        m=fork();
        printf("PID:%d	",getpid());
        printf("The return value of fork():%d		",m);
        printf("he
    ");
        n=fork();
        printf("PID:%d	",getpid());
        printf("The return value of fork():%d		",n);
        printf("ha
    ");
        k=fork();
        printf("PID:%d	",getpid());
        printf("The return value of fork():%d		",k);
        printf("ho
    ");
    }

    结果

    分析

    父进程运行,4135进程依次经由m/n/k=fork()产生三个子进程4136,4137,4138

    4137进程运行,经由k=fork()产生子进程4139

    4136进程运行,经由n/k=fork()产生子进程4140,4141

    4139进程运行

    4141进程运行

    4140进程运行,经由k=fork()产生子进程4142

    4142进程运行

    进程树

    代码4

     

    /*test4*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    int main(){
    int p1,p2,i;
    FILE *fp;
    fp = fopen("1.txt", "w+");
    
    while((p1=fork())==-1);
    if(p1==0)
        for(i=0;i<50000;i++)
        fprintf(fp,"son%d
    ",i);
    else
        {
        while((p2=fork())==-1);
        if(p2==0)
        for(i=0;i<50000;i++)
        fprintf(fp,"daughter%d
    ",i);
        else
        for(i=0;i<50000;i++)
        fprintf(fp,"parent%d
    )",i);
        }
    }

    结果

    分析

    Parent进程经由while((p1=fork())==-1),while((p2=fork())==-1)分别产生子进程son,daughter

    每个进程经由分支会进入一个长度为50000的循环,循环过程中其运行会被交替打断

    进程树

    与test1_2相同

    • 题目1

      代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    int main()
    {
        int p1,p2,p3;
        while((p1=fork())==-1);
        if(p1!=0)printf("fork p1 ,pa:%d ,son:%d
    ",getpid(),p1);
        else printf("b1's id is%d
    ",getpid());
        
        while((p2=fork())==-1);
        if(p2!=0){
            printf("fork p2 ,pa:%d ,son:%d
    ",getpid(),p2);
            if(p1!=0){
                while((p3=fork())==-1);
                    if(p3!=0){
                        printf("fork p3 ,pa:%d ,son:%d
    ",getpid(),p3);
                        printf("a1 id is%d
    ",getpid());
                    }
                    else{
                        printf("b3 id is%d
    ",getpid());
                    }
            }
            }
        else if(p1!=0)printf("b2's id is%d
    ",getpid());
        else printf("c1's id is%d
    ",getpid());
    }

     

    结果

    进程树

    • 题目2

    代码

    /*test4*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    int main(){
    int p1,p2,i;
    FILE *fp;
    fp = fopen("1.txt", "w+");
    
    while((p1=fork())==-1);
    if(p1==0){
        lockf(1,1,0);
        //fprintf(fp,"locking~
    ");
        for(i=0;i<70000;i++)
        fprintf(fp,"son%d
    ",i);
        //fprintf(fp,"unlocking~
    ");
        lockf(1,0,0);
    }
    else{
        while((p2=fork())==-1);
        if(p2==0){
            lockf(1,1,0);
            //fprintf(fp,"locking~
    ");
            for(i=0;i<70000;i++)
            fprintf(fp,"daughter%d
    ",i);
            //fprintf(fp,"unlocking~
    ");
            lockf(1,0,0);
        }
        else{
            lockf(1,1,0);
            //fprintf(fp,"locking~
    ");
            for(i=0;i<70000;i++)
            fprintf(fp,"parent%d
    )",i);
            //fprintf(fp,"unlocking~
    ");
            lockf(1,0,0);
        }
    }
    }

    结果分析

    对于运行结果,在别人的虚拟机上运行可以实现加锁代码段运行时完全被锁,而在我自己的虚拟机上运行时只能是大部分时间的锁定,而非完全锁定,结果如下:

    当循环长度为1000时:

    可以保证在100%的运行时间段内都不被打断。

    当循环长度是10000是:

    可以保证在100%的运行时间段内都不被打断。

    当循环长度是50000时:

    会在运行将近结束的时候被打断,被打断的时间点是固定的,parent进程会在i=49690处被打断,daughter会在i=49944处被打断

    接续被打断的时间则是随机的。

    当循环长度是100000时:

    Parent会在i=99787处被打断,daughter会在i=99974处被打断。

    打断和接续情况与之前相同,仍是打断时间固定,接续时间随机。

    目前原因尚未得知,推测与io中断处理有关。

    实验心得

          通过此次实验,了解并掌握了linux系统虚拟机的基本使用方法。由于linux的内核较为简单且其有大量跨平台的硬件支持,大部分是用C 语言编写的,所以有助于操作系统课程的学习和实践。

          在实验中也初步对linux的进程管理产生了了解,但学习尚不深入,仍有许多不甚明了的问题,如:在不同电脑上(vmvare和ubuntu镜像版本相同)程序2中a,b,c进程的运行顺序不同;程序设计问题二中的Lockf处理结果也不同。这些问题留给未来的操作系统学习过程中解决。

  • 相关阅读:
    MATLAB数据处理快速学习教程
    dev -c++ 快捷键
    SQL 通配符
    如何利用SQL语句求日期的时间差值,并汇总网上的一些信息
    matlab使用常犯的错误
    matlab中将矩阵按照行打乱顺序的一个例子
    我所认识的PCA算法的princomp函数与经历 (基于matlab)
    java 读取本地的json文件
    Oracle数据库——SQL基本查询
    Oracle数据库——表的创建与管理
  • 原文地址:https://www.cnblogs.com/-ifrush/p/14132351.html
Copyright © 2011-2022 走看看