FZU操作系统课程实验 实验一
实验1
【实验名称】:并发程序设计(实验1)
【实验目的】:掌握在程序中创建新进程的方法, 观察并理解多道程序并发运行的现象。
【实验原理】:fork():建立子进程。子进程得到父进程地址空间的一个复制。
返回值:成功时,该函数被调用一次,但返回两次,fork()对子进程返回0,对父进程返回子进程标识符(非0值)。不成功时对父进程返回-1,没有子进程。
【实验内容】:首先分析一下程序执行时其输出结果有哪几种可能性,然后实际调试该程序观察事实上际输出情况,比較两者的差异,分析当中的原因。
void main (void)
{
int x=5;
if( fork( ) )
{
x+=30;
printf (“%d\n”,x);
}
else
printf(“%d\n”,x);
printf((“%d\n”,x);
}
【实验要求】:每一个同学必须独立完毕本实验、提交实验报告、源程序和可运行程序。实验报告中必须包括估计的实验结果,关键代码的分析,调试记录,实际的实验结果,实验结果分析等内容。
一.关键代码分析
值而父进程中返回子进程ID。
子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。
也就是说,当程序执行到if条件推断执行fork()函数后,父进程执行的是条件成立成立的代码,即
x+=30;
printf (“%d\n”,x);
子进程执行的是条件不成立的代码,即
printf(“%d\n”,x);
依据并发运行的工作方式及特征,我们估计可能的实验结果例如以下:
二.估计实验结果
推測有6种情况(事实上就是这4个数的全排列)
35 |
35 |
35 |
5 |
5 |
5 |
35 |
5 |
5 |
5 |
35 |
35 |
5 |
35 |
5 |
35 |
5 |
35 |
5 |
5 |
35 |
35 |
35 |
5 |
三.调试记录
1. 先建立一个.c为后缀的文档,如test.c
2. 编辑源程序:
#include<stdio.h>
#include<unistd.h>
void main (void)
{
int x=5;
if( fork( ) )
{
x+=30;
printf (“%d\n”,x);
}
else
printf(“%d\n”,x);
printf((“%d\n”,x);
}
3. 在命令行下编辑 gcc –o test.out test.c
然后编辑 ./test.out
执行程序
4. 实际实验结果:
35
35
(一串字符命令,省略)5
5
(PS:那段字符命令,父进程执行完就会出现,所以都是在输出两个35后出现)
反复步骤3,N次后发现还是这个结果。
四.实验结果分析
老师说其他结果的出现是小概率事件。我们不敢苟同,这都基本上能够当不可能事件处理了。
于是我们推測,这个跟传说中的时间片有关。
由于这个程序执行所需的时间实在是太短,默认先执行的父进程全然能够在系统给定的时间片内执行完,假设没有出现什么其它情况而挂起,子进程就仅仅能等到父进程执行完后才干执行。
所以呢,当然就仅仅有一种情况了。
五.实验结果处理
只是,我们能够利用时间片的特性制造出6种结果。
主角登场了,sleep(1) 延时一秒函数
能够把延时函数理解为一段要执行1秒的代码。以下的提到的进程,都是因在这段延时代码中执行时进程时间片用完挂起(如果在这个延时代码中执行了0.6秒),再次调度回来时,仅仅要再执行0.4秒就能够了跳出这个延时函数了。
第一种:
由于默认先执行的是父进程(我用的系统是这样),我们感觉对子进程太不公平了,所以我们制造的第一种情况的源代码是:
#include<stdio.h>
#include<unistd.h>
void main (void)
{ int x=5;
if( fork( ) )
{
x+=30;
sleep(1);
printf (“%d\n”,x);
}
else
printf(“%d\n”,x);
printf((“%d\n”,x);
}
我们推測时间片是0.6秒,无论对不正确,重点是分析。
父进程执行0.6秒后,时间片用完挂起,调度执行子进程,子进程执行完后调度回父进程接着执行。所以我们推測结果是
5
5
35
35
(一串字符命令,省略)
哇塞,执行完也是!
另外一种:
这里我们突然想到假设在子进程前也加个延时函数会如何,
#include<stdio.h>
#include<unistd.h>
void main (void)
{ int x=5;
if( fork( ) )
{
x+=30;
sleep(1);
printf (“%d\n”,x);
}
else {
sleep(1);
printf(“%d\n”,x);
}
printf((“%d\n”,x);
}
只是,这个仅仅能调试完再依据答案去分析,由于我们也不知道真正的时间片是多少,仅仅是推測。执行结果为
35
35
(一串字符命令,省略)5
5
我们继续如果时间片为0.6秒,父进程执行0.6秒后挂起,轮到子进程执行0.6秒后也挂起,调度回父进程继续执行,由于之前已经执行了0.6秒,所以这次调度时间片就够用了。如果成立
所以,下面都是如果时间片为0.6秒,这个时间是非常合理的。
第三种:
#include<stdio.h>
#include<unistd.h>
void main (void)
{
int x=5;
if( fork( ) )
{
x+=30;
sleep(1);
printf (“%d\n”,x);
}
else {
printf(“%d\n”,x);
sleep(1);
}
printf((“%d\n”,x);
}
与前面的分析类似,父进程执行0.6秒后挂起,调度子进程会先执行第一条指令输出x为5,然后进入延时函数执行0.6秒(前面执行1条指令的时间能够忽略不计)后挂起,调度回父进程执行完,再调度回子进程。所以输出为
5
35
35
(一串字符应该是提示输入的命令,省略)5
第四种:
#include<stdio.h>
#include<unistd.h>
void main (void)
{ int x=5;
if( fork( ) )
{
x+=30;
printf (“%d\n”,x);
sleep(1);
}
else {
printf(“%d\n”,x);
sleep(1);
}
printf((“%d\n”,x);
}
分析同上,输出结果为
35
5
35
(一串字符命令,省略)5
第五种:
#include<stdio.h>
#include<unistd.h>
void main (void)
{ int x=5;
if( fork( ) )
{
x+=30;
printf (“%d\n”,x);
sleep(1);
}
else {
printf(“%d\n”,x);
}
printf((“%d\n”,x);
}
执行结果为,
35
5
5
35
(一串字符命令,省略)
第六种:
细致看下上面5种情况,会发现还有种比較奇葩的没有出现。
5
35
5
35
(一串字符命令,省略)
须要从父进程(延时挂起)->子进程(输出然后延时挂起)->父进程(延时然后输出然后再延时挂起)->子进程(输出结束进程)->父进程(延时然后输出结束进程),代码为
#include<stdio.h>
#include<unistd.h>
void main (void)
{ int x=5;
if( fork( ) )
{
x+=30;
sleep(1);
printf (“%d\n”,x);
sleep(1);
}
else {
printf(“%d\n”,x);
sleep(1);
}
printf((“%d\n”,x);
}
FZU操作系统课程实验 实验一的更多相关文章
- 第七周课程总结&实验报考(五)
第七周课程总结&实验报考(五) 实验四 类的继承 实验目的: 1.理解抽象类与接口的使用: 2.了解包的作用,掌握包的设计方法. 实验要求: 1.掌握使用抽象类的方法. 2.掌握使用系统接口的 ...
- 实验5 简单嵌入式WEB服务器实验 实验报告 20135303 20135326
北京电子科技学院(BESTI) 实 验 报 告 课程:信息安全系统设计基础 班级: 1353 姓名:20135303 魏昊卿 学号:2013532 ...
- 20145317彭垚 《Java程序设计》第一次实验实验报告
20145317彭垚 <Java程序设计>第一次实验实验报告 北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1453 指导教师:娄嘉鹏 实验名称:Java开发环境的 ...
- 20144303 《Java程序设计》第一次实验实验报告
20144303 <Java程序设计>第一次实验实验报告 北京电子科技学院(besti)实验报告 课程:java程序设计 班级:1453 指导教师:娄嘉鹏 实验日期:2016.04.08 ...
- 20144303 《Java程序设计》第二次实验实验报告
20144303 <Java程序设计>第二次实验实验报告 北京电子科技学院(besti)实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握U ...
- 第八周课程总结&实验报告(六)
第八周课程总结 启动多线程售票(上课老师说要加入作业的部分) public class TestDemo { public static void main(StringD args) throws ...
- 第五周课程总结&实验报告(四)
第五周课程总结 本周主要学习了 1.抽象类 抽象类的定义格式 abstract class抽象类名称{ 属性; 访问权限返回值类型方法名称(参数){ //普通方法 [return返回值]; } 访问权 ...
- 第四周课程总结&实验报告(二)
Java实验报告(二) 实验二 Java简单类与对象 一. 实验目的 (1) 掌握类的定义,熟悉属性.构造函数.方法的作用,掌握用类作为类型声明变量和方法返回值: (2) 理解类和对象的区别,掌握构造 ...
- 第四周课程总结&实验报告二
第四周课程总结 第四周课程总结 本周重点为学习String;首先String用以创建字符串,且通过有一次课堂练习加强理解到:String 类是不可改变的,一旦创建了 String 对象,那它的值就无法 ...
随机推荐
- Adb shell得到root才干
于Adb shell我们希望用一些文件系统文件夹时,经常有在没有痛苦Root才干,系统会提示su: Permission Denied. su不是每个手机有一个.能不能在这里下载: http://do ...
- dapper支持oracle游标
dapper支持oracle游标 Dapper是一个轻型的ORM类.它有啥优点.缺点相信很多朋友都知道了,园里也有很多朋友都有相关介绍,这里就不多废话. 如果玩过Oracle都知道,存储过程基本都是通 ...
- MailTest
GridBagLayout把一个界面分为m行n列的网格 GridBagConstraints的一个实例:gridx = 2; // X2,表示组件位于第2列gridy = 0; // Y0,表示组件位 ...
- SDL2来源分析3:渲染(SDL_Renderer)
===================================================== SDL源代码分析系列文章上市: SDL2源码分析1:初始化(SDL_Init()) SDL2 ...
- win32使用拖放文件
于win32规划,使用拖放文件操作,非经常见(不否认有些人喜欢用button打开) 中使用拖拽,非常easy,仅仅须要在创建窗体的时候使用WS_EX_ACCEPTFILES标识符,然后使用一个消息函数 ...
- 8、Cocos2dx 3.0三,找一个小游戏开发3.0存储器管理的版本号
重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27693365 复杂的内存管理 移动设备上的硬件资源十 ...
- PE文件结构(四) 输出表
PE文件结构(四) 參考 书:<加密与解密> 视频:小甲鱼 解密系列 视频 输出表 一般来说输出表存在于dll中.输出表提供了 文件里函数的名字跟这些函数的地址, PE装载器通过输出表来改 ...
- WPF学习(1)WPF概述
WPF(Windows Presentation Foundation)是微软推出的基于Windows Vista的用户界面框架,属于NET Framework 3.0的一部分.它提供了统一的编程模型 ...
- SQL Server 内存泄露(memory leak)——游标导致的内存问题
原文:SQL Server 内存泄露(memory leak)--游标导致的内存问题 转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/07/01/sql ...
- 定制Attribute
目录 Attribute是什么 自定义Attribute 一.Attribute是什么 将一些附加信息与制定目标相关联的方式.编译器在元数据中生成这些额外的信息.也叫做特性. 比如之前文章中提到的:枚 ...