计算机实验进程管理与虚拟机,12.14 操作系统实验:linux虚拟机与进程管理

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

实验目的

了解linux虚拟机的用途及 基本使用步骤

了解进程调度的目的及应用场景

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

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

实验内容

使用文件相关的linux的基础命令

运行进程处理的代码段,并解释结果

对于给定的进程处理问题,可以自行设计解决方案并代码实现

代码及运行结果分析

1.linux基础文件命令使用

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

665613a34ac5774784e7df9c19b31c4b.png

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

移动

c5a7b5b7d7b89ef9623c180dfaf1db6f.png

重命名

88d2807f830b82573d9c8154df7b0342.png

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

文件

c81aa06f01f083440003ebe23014a16b.png

目录

719d2b32f6c423cb8e600dd03f945d98.png

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

c61600e556233d0aa94cd940d9cc0755.png

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

756758c97d80ccd034c7b4e73d858e75.png

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

fc358444b74fb7569f58abd6657d04f4.png

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

0a361727cc98eccc09224ecce4aaab58.png

复制文件命令cp ,cp -rf

37e80f4329f0e7e2274cdd4d1629bc45.png

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

cc9b519633d4cee1b8a5e05547305087.png

2.进程管理

代码修正及结果分析

代码1

/*test1*/#include#include#include#include#include

intmain()

{inti,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);

}

}

结果

dbd678de45a345a1caa64dfc4db522ec.png

分析

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

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

进程树

cc88d118e41cd19795c134b8b84df737.png

代码2

/*test2*/#include#include#include#include

intmain()

{intp1,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());elseprintf("a.My process ID is %d",getpid());

}

}

结果

a7a5167478225b38cd55edbee174b81a.png

分析

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

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

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

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

进程树

1e6ae3717b9509389a3cc0506ae12d28.png

代码3

/*test3*/#include#include#include#include

intmain()

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

}

结果

92776abecd9b190d0ceb2591c0b83906.png

分析

父进程运行,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进程运行

进程树

ff9dac9796da36a8557d26926697e0af.png

代码4

/*test4*/#include#include#include#include

intmain(){intp1,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);

}

}

结果

1dd7664afe0b262729fe7a4ca2f958e8.png

分析

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

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

进程树

与test1_2相同

题目1

代码

#include #include#include#include

intmain()

{intp1,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());

}

结果

e7d4eb4127ea668926c7f1bbabfbb40e.png

进程树

2d67c7dafb9b786fb28d483a65f44d77.png

题目2

代码

/*test4*/#include#include#include#include

intmain(){intp1,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时:

c705375578ad90d6ef903e37ae064c2b.png

4027f69e97ea2c898f3a700083473466.png

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

当循环长度是10000是:

62c10a129358c71965b0522a311c6ce8.png

fa42cfd0b446336b28e0ccc52d671639.png

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

当循环长度是50000时:

ac0dd65f8002786e170cb39fe94eb05b.png

a62503ef829faabaa9d70e4e39ee0f94.png

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

ce212b692c86fe8c3f2e648a7fe5cc93.png

a61563d42c01ec14bce7ef3b444b12c4.png

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

当循环长度是100000时:

f264af3f8e1d754a8f26340bf9d72b04.png

33331cd519c037f7f2307944f235fad0.png

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

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

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

实验心得

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

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

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
操作系统进程调度是计算机操作系统中的一个重要部分,它负责协调和管理系统中的各个进程,以实现资源的有效利用和任务的高效执行。在C语言中进行操作系统进程调度实验,可以通过模拟不同的调度算法来理解和掌握进程调度的原理和实现过程。 首先,可以使用C语言编写一个简单的程序,模拟进程的创建、就绪、运行和结束等状态。通过定义进程控制块(PCB)、进程队列等数据结构,以及编写相应的进程管理函数,来实现对进程管理和调度。例如,可以编写函数来创建新进程、将进程加入就绪队列、根据调度算法选择下一个要执行的进程等。 其次,可以选择不同的调度算法来实验,如先来先服务(FCFS)、最短作业优先(SJF)、时间片轮转(RR)等。针对不同的调度算法,通过C语言实现相应的调度函数,并在模拟程序中进行调用,观察不同算法对进程执行顺序和响应时间的影响。 最后,可以通过对进程调度实验的结果进行分析和比较,来深入理解各种调度算法的优缺点,以及在不同场景下的适用性。同时,也可以通过进一步的实验和优化,来改进模拟程序,增加更多的实际场景和特性,以更好地理解和应用操作系统进程调度的相关知识。 通过C语言进行操作系统进程调度实验,可以帮助我们更深入地理解和掌握操作系统的核心概念和原理,为今后的系统设计和开发打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值