石家庄铁道大学
实验报告
课程名称操作系统(B)
专业数字媒体技术
学生姓名王赛赛
班级信1406
学号20142988
任课教师沙金
完成日期2015 年 112月 1日
信息科学与技术学院
1
实验二进程同步
一、实验目的
处理机调度是处理机管理的核心内容。本实验要求用高级语言编写模拟进程调度程序,以便加深理解有关进程控制快、进程队列等概念,并体会和了解进程调度算法的具体实施办法。
二、实验内容
(1)编写一个进程调度模拟程序,实现以下调度算法:先来先服务调度,
时间片轮转调度算法,短作业优先调度算法,最高响应比优先调度算法,多级反
馈队列调度算法。
(2)计算平均周转时间和平均带权的周转时间。
(3)先来先服务调度,短作业优先调度算法测试用例。
(4)时间片为 4 的轮转调度算法的测试用例。
(5)最高响应比优先调度算法的测试用例。
(6)多级反馈队列调度算法的测试用例。
三、实验要求
1.设计进程控制块PCB 的结构,通常应包括如下信息:
进程名、进程优先数(或轮转时间片数)、进程已占用的 CPU 时间、进程
到完成还需要的时间、进程的状态、当前队列指针等。
2.能演示进程调度过程。
3.界面友好。
4.实验报告书写请参考附录
四、设计原理
1.每个进程可有三种状态;执行状态(RUN)、就绪状态(READY,包括等待状态)和完成状态(FINISH),并假定初始状态为就绪状态。
2.主程序定义PCB 结构和其他有关变量,每个调度算法用一个子程序实现。
3.进程控制块结构参考:
NAME——进程标示符
PRIO/ROUND——进程优先数/进程每次轮转的时间片数(设为常数 2)CPUTIME——进程累计占用CPU 的时间片数
NEEDTIME——进程到完成还需要的时间片数
STATE——进程状态3
NEXT——链指针
注:(1)为了便于处理,程序中进程的的运行时间以时间片为单位进行计算;(2)各进程的优先数或轮转时间片数,以及进程运行时间片数的初值,均由
用户在程序运行时给定。
4.进程的就绪态和等待态均为链表结构。
5.在优先数算法中,进程优先数的初值设为:
50-NEEDTIME
每执行一次,优先数减1,CPU 时间片数加1,进程还需要的时间片数减1。6.在轮转法中,采用固定时间片单位(两个时间片为一个单位),进程每轮
转一次,CPU 时间片数加 2,进程还需要的时间片数减 2,并退出 CPU,排到就绪
队列尾,等待下一次调度。
六:程序清单
#include
#include
#include
#include
using namespace std;
//hyugtyftydrtdtrdrrtrdrt
struct Node
{
string name;//进程(作业)名称
int arriveTime;//到达时间
int ServerTime;//服务时间
int leftTime;//the left time
Node *link;//指向下一个节点的指针
};
class CProcess
{
public:
CProcess();//构造函数
~CProcess();//析构函数
const CProcess &operator =(const CProcess& p);//重载赋值操作符
void insertNode(string &na,int& at,int& st);//插入新元素(at由小到大)到链表合适的位置
void sort();//按照服务时间由大到小排序
bool isEmpty();//判断是否为空
void destroy();//销毁
int length();//求出链表长度
void print();//打印出元素
void FCFS();//先到先服务
void SJF();//短进程(作业)优先
void RR(int& q);//时间片轮转
void priority();//优先权调度
protected:
Node *first;
Node *last;
};
const CProcess& CProcess::operator=(const CProcess& p)
{
Node *newNode;
Node *Current;
if(this!=&p)//避免自己给自己赋值
{
if(first!=NULL)//如果链表不为空
destroy();
if(p.first==NULL)
{
//如果要拷贝的对象为空
this->first = NULL;
this->last = NULL;
}
else
{
Current = p.first;
first= new Node;
first->name=Current->name;//
first->arriveTime=Current->arriveTime;
first->ServerTime=Current->ServerTime;
first->link =NULL;
last =first;
Current = Current->link;
while(Current!=NULL)
{
newNode = new Node;
newNode->name=Current->name;
newNode->arriveTime=Current->arriveTime;
newNode->ServerTime=Current->ServerTime;
newNode->link=NULL;
last->link=newNode;
last=newNode;
Current = Current->link;
}
}
}
return *this;
}
CProcess::CProcess()
{//构造函数
first=NULL;
last=NULL;
}
CProcess::~CProcess()
{
Node *temp;
while(first!=NULL)
{
temp=first;
first=first->link;
delete temp;
}
last=NULL;
}
void CProcess::insertNode(string &na,int& at,int& st)
{//按照到达时间升序排序
Node *Current;
Node *trailCurrent;//指向Current的前一个节点
Node *newNode;
bool found;
newNode = new Node;//建立一个新节点
newNode->name=na;
newNode->arriveTime=at;
newNode->ServerTime=st;
newNode->link=NULL;//
if(first==NULL)//如果第一个节点为空(如果是第一次插入元素)first=newNode;//将新节点赋给第一个节点
else
{//如果不是第一次
Current =first;
found = false;
while(Current!=NULL && !found)
{
if(Current->arriveTime >= at)
found = true;
else
{
trailCurrent = Current;
Current = Current->link;
}
}
if(Current==first)
{
newNode->link = first;
first = newNode;
}
else
{
trailCurrent->link = newNode;
newNode->link = Current;
}
}
}
int CProcess::length()
{
int count =0;//声明变量,并初始化为0(用来记录长度)
Node *Current;
Current = first;
while(Current!=NULL)//当前节点不为空,记录值自加,一直向后遍历,
{
count++;
Current = Current->link;
}
return count;//返回长度
}
void CProcess::sort()//按照服务时间,升序排列
{//冒泡排序
string sname;
int at;
int st;
Node *Current;//指向当前节点
Node *trailCurrent;//指向当前节点的前一个节点
for(trailCurrent=first->link;trailCurrent!=NULL;trailCurrent=trailCurrent->link)//控制条件有问题{
for(Current=trailCurrent->link;Current!=NULL;Current=Current->link)//控制条件有问题{
if(trailCurrent->ServerTime > Current->ServerTime)
{
sname=trailCurrent->name;
at=trailCurrent->arriveTime;
st=trailCurrent->ServerTime;
trailCurrent->name=Current->name;
trailCurrent->arriveTime=Current->arriveTime;
trailCurrent->ServerTime=Current->ServerTime;
Current->name=sname;
Current->arriveTime=at;
Current->ServerTime=st;
}
}
}
}
bool CProcess::isEmpty()//判断是否为空
{
return (first==NULL);//如果第一个节点为空,返回值
}
void CProcess::print()
{
Node *Current;
Current = first->link;//头节点赋给当前节点
while(Current!=NULL)//当前节点不为空,一直向后遍历打印
{
cout<
cout<
cout<
Current = Current->link;
}
}
void CProcess::destroy()
{
Node *temp;//定义一个临时指针变量
while(first!=NULL)
{
temp=first;
first=first->link;
delete temp;
}
last=NULL;
}
void CProcess::FCFS()//先到先服务
{
Node *Current;
int T0=0;//完成时间
int T1=0;//周转时间
Current = first->link;//头节点赋给当前节点while(Current!=NULL)
{
if(T0 < Current->arriveTime)
{
T0=Current->arriveTime+Current->ServerTime; T1=T0-Current->arriveTime;
cout<
cout< cout< Current = Current->link; } else { T0=Current->ServerTime+T0; T1=T0-Current->arriveTime;//周转时间等于,完成时间 - 到达时间cout< cout< cout< Current = Current->link; } } } void CProcess::SJF()//短进程(作业)优先 { //首先执行第一个到达的作业 Node *Current; int T0=0;//完成时间 int T1=0;//周转时间 T0=first->link->ServerTime+T0; T1=T0-first->link->arriveTime; cout< cout< cout< first->link=first->link->link;//删除 //执行剩下的 sort();//对剩下的排序 Current = first->link;//头节点赋给当前节点 while(Current!=NULL) { if(T0 < Current->arriveTime) { T0=Current->arriveTime+Current->ServerTime; T1=T0-Current->arriveTime; cout< cout< cout< Current = Current->link; } else { T0=Current->ServerTime+T0; T1=T0-Current->arriveTime;//周转时间等于,完成时间 - 到达时间cout< cout< cout< Current = Current->link; } } } void CProcess::RR(int& q)//时间片轮转 { cout<<"时间片轮转操作完成!\n"; } void CProcess::priority()//优先权调度 { cout<<"优先权操作完成!\n"; } void main() { CProcess p0,p1,p2,p3,p4; int at,st; string na; int judge=1;//控制退出程序 int choice;//控制选择操作 while(judge) { cout<<"****** 说明:本程序适用于单道进程(作业) ******\n"; cout<<"*******请选择您的操作 ***************\n"; cout<<"*******输入相应的数字,按下(Enter)键!**************\n"; cout<<"*******5.录入信息 ************\n"; cout<<"*******1.先到先服务 ************\n"; cout<<"*******2.短进程(作业)优先 ************\n"; cout<<"*******3.时间片轮转 ************\n"; cout<<"*******4.优先权(静态)调度 ************\n"; cout<<"*******0.退出程序 ************\n"; cin>>choice; switch(choice) { case 0: judge=0; break; case 5: cout<<"请输入信息以“end”结束输入!\n"; cout<<"进程名到达时间服务时间"< while(https://www.doczj.com/doc/9918594585.html,pare("end"))//如果相等则会返回0 { p0.insertNode(na,at,st); cin>>na>>at>>st; } cout<<"录入成功,目前的信息为:\n"; cout<<"进程名到达时间服务时间"< break; case 1://先到先服务 p1=p0;//拷贝一份 if(p1.isEmpty()) { cout<<"请先录入信息\n"; break; } else { cout<<"先到先服务\n"; cout<<"进程名完成时间周转时间\n"; p1.FCFS(); break; } case 2://短作业优先 p2=p0;//拷贝一份 //p2.sort(); //p2.print(); if(p2.isEmpty()) { cout<<"请先录入信息\n"; break; } else { cout<<"短作业优先\n"; cout<<"进程名完成时间周转时间\n"; p2.SJF(); break; } case 3://时间片轮转 p3=p0;//拷贝一份 int q; if(p3.isEmpty()) { cout<<"请先录入信息\n"; break; } else { cout<<"请输入时间片大小"; cin>>q; cout<<"时间片轮转\n"; cout<<"进程名完成时间周转时间\n"; p3.RR(q); break; } case 4://优先权 p4=p0;//拷贝一份 if(p4.isEmpty()) { cout<<"请先录入信息\n"; break; } else { cout<<"时间片轮转\n"; cout<<"进程名完成时间周转时间\n"; p4.priority(); break; } default: cout<<"请选择目录中的选项!\n"; break; } } return; } 七:运行结果 八:心得体会与总结 本次实验成功的完成了短作业优先调度算法和轮转时间片调度算法等五种的模拟,通过本次实验我们了解到短作业优先调度算法不利于长作业的处理,因为长作业将长期得不到处理,而轮转时间片调度算法则解决了这一问题。短长作业均能在每一个周期内分得一个时间片处理自己的任务。通过本次实验对程序算法能力有了进一步的提高,同时对模块化编程有了更深入得理解,代码的模 块化会使程序的代码复用率提高,提高编程的效率。 计算机操作系统进程调度实验研究报告 ————————————————————————————————作者:————————————————————————————————日期: 操作系统实验题:设计一若干并发进程的进程调度程序 一、实验目的 无论是批处理系统、分时系统还是实时系统,用户进程数一般都大于处理机数,这将导致用户进程互相争夺处理机。这就要求进程调度程序按一定的策略,动态地把处理及分配给处于就绪队列中的某一进程,以使之执行。进程调度是处理机管理的核心内容。本实验要求采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法编写和调试一个简单的进程调度程序。通过本实验可以加深理解有关进程控制块、进程队列的概念。并体会了优先数和先来先服务调度算法的具体实施办法。 二、实验要求 用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解. 三、实验内容 进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法(将用户作业和就绪进程按提交顺序或变为就绪状态的先后排成队列,并按照先来先服务的方式进行调度处理)。 每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。 进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。 进程的运行时间以时间片为单位进行计算。 每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。 就绪进程获得CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。 如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。 每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。重复以上过程,直到所要进程都完成为止。 四、实验算法流程 实验一进程管理 一、目的 进程调度是处理机管理的核心内容。本实验要求编写和调试一个简单的进程调度程序。通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法的具体实施办法。 二、实验内容及要求 1、设计进程控制块PCB的结构(PCB结构通常包括以下信息:进程名(进程ID)、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等。可根据实验的不同,PCB结构的内容可以作适当的增删)。为了便于处理,程序中的某进程运行时间以时间片为单位计算。各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定。 2、系统资源(r1…r w),共有w类,每类数目为r1…r w。随机产生n进程P i(id,s(j,k),t),0<=i<=n,0<=j<=m,0<=k<=dt为总运行时间,在运行过程中,会随机申请新的资源。 3、每个进程可有三个状态(即就绪状态W、运行状态R、等待或阻塞状态B),并假设初始状态为就绪状态。建立进程就绪队列。 4、编制进程调度算法:时间片轮转调度算法 本程序用该算法对n个进程进行调度,进程每执行一次,CPU时间片数加1,进程还需要的时间片数减1。在调度算法中,采用固定时间片(即:每执行一次进程,该进程的执行时间片数为已执行了1个单位),这时,CPU时间片数加1,进程还需要的时间片数减1,并排列到就绪队列的尾上。 三、实验环境 操作系统环境:Windows系统。 编程语言:C#。 四、实验思路和设计 1、程序流程图 2、主要程序代码 //PCB结构体 struct pcb { public int id; //进程ID public int ra; //所需资源A的数量 public int rb; //所需资源B的数量 public int rc; //所需资源C的数量 public int ntime; //所需的时间片个数 public int rtime; //已经运行的时间片个数 public char state; //进程状态,W(等待)、R(运行)、B(阻塞) //public int next; } ArrayList hready = new ArrayList(); ArrayList hblock = new ArrayList(); Random random = new Random(); //ArrayList p = new ArrayList(); int m, n, r, a,a1, b,b1, c,c1, h = 0, i = 1, time1Inteval;//m为要模拟的进程个数,n为初始化进程个数 //r为可随机产生的进程数(r=m-n) //a,b,c分别为A,B,C三类资源的总量 //i为进城计数,i=1…n //h为运行的时间片次数,time1Inteval为时间片大小(毫秒) //对进程进行初始化,建立就绪数组、阻塞数组。 public void input()//对进程进行初始化,建立就绪队列、阻塞队列 { m = int.Parse(textBox4.Text); n = int.Parse(textBox5.Text); a = int.Parse(textBox6.Text); b = int.Parse(textBox7.Text); c = int.Parse(textBox8.Text); a1 = a; b1 = b; c1 = c; r = m - n; time1Inteval = int.Parse(textBox9.Text); timer1.Interval = time1Inteval; for (i = 1; i <= n; i++) { pcb jincheng = new pcb(); jincheng.id = i; jincheng.ra = (random.Next(a) + 1); jincheng.rb = (random.Next(b) + 1); jincheng.rc = (random.Next(c) + 1); jincheng.ntime = (random.Next(1, 5)); jincheng.rtime = 0; 实验三:进程同步实验 一、实验任务: (1)掌握操作系统的进程同步原理; (2)熟悉linux的进程同步原语; (3 )设计程序,实现经典进程同步问题。 二、实验原理: (1)P、V操作 PV操作由P操作原语和V操作原语组成(原语是不可中断的过程) ,对信号量进行操作,具体定义如下: P( S):①将信- 号量S的值减1,即S=S-1; ②如果S30,则该进程继续执行;否则该进程置为等待状态,排入等待队列。 V( S):①将信号量S的值加1,即S=S+1 ; ②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。 (2)信号量 信号量(semaphore )的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,信号量的 值仅能由PV操作来改变。 一般来说,信号量S30时,S表示可用资源的数量。执行一次P操作意味着请求分配一 个单位资源,因此S的值减1;当S<0时,表示已经没有可用资源,请求者必须等待别的进程释放该类资源,它才能运行下去。而执行一个V操作意味着释放一个单位资源,因此S 的值加1;若S均,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。 (3)linux的进程同步原语 ①wait();阻塞父进程,子进程执行; ②#in clude 实验一、进程控制实验 1.1 实验目的 加深对于进程并发执行概念的理解。实践并发进程的创建和控制方法。观察和体验进程的动态特性。进一步理解进程生命期期间创建、变换、撤销状态变换的过程。掌握进程控制的方法,了解父子进程间的控制和协作关系。练习Linux 系统中进程创建与控制有关的系统调用的编程和调试技术。 1.2 实验说明 1)与进程创建、执行有关的系统调用说明进程可以通过系统调用fork()创建子进程并和其子进程并发执行.子进程初始的执行映像是父进程的一个复本.子进程可以通过exec()系统调用族装入一个新的执行程序。父进程可以使用wait()或waitpid()系统调用等待子进程的结束并负责收集和清理子进程的退出状态。 fork()系统调用语法: #include Exec 执行成功后将用一个新的程序代替原进程,但进程号不变,它绝不会再返回到调用进程了。如果exec 调用失败,它会返回-1。 wait() 系统调用语法: #include 《计算机操作系统2》实验报告 实验一题目:操作系统的进程调度 姓名:学号:12125807 实验日期:2014.12 实验要求: 1.设计一个有n个进程工行的进程调度程序。每个进程由一个进程控制块(PCB)表示。 进程控制块通常应包含下述信息:进程名、进程优先数、进程需要运行的时间、占用CPU的时间以及进程的状态等,且可按调度算法的不同而增删。 2.调度程序应包含2~3种不同的调度算法,运行时可任意选一种,以利于各种算法的分 析比较。 3.系统应能显示或打印各进程状态和参数的变化情况,便于观察诸进程的调度过程 实验目的: 1.进程是操作系统最重要的概念之一,进程调度又是操作系统核心的主要内容。本实习要 求学生独立地用高级语言编写和调试一个简单的进程调度程序。调度算法可任意选择或自行设计。例如,简单轮转法和优先数法等。本实习可加深对于进程调度和各种调度算法的理解。 实验内容: 1.编制和调试示例给出的进程调度程序,并使其投入运行。 2.自行设计或改写一个进程调度程序,在相应机器上调试和运行该程序,其功能应该不亚 于示例。 3.直观地评测各种调度算法的性能。 示例: 1.题目 本程序可选用优先数法或简单轮转法对五个进程进行调度。每个进程处于运行R(run)、就绪W(wait)和完成F(finish)三种状态之一,并假设起始状态都是就绪状态W。为了便于处理,程序进程的运行时间以时间片为单位计算。各进程的优先数或轮转时间片数、以及进程需要运行的时间片数,均由伪随机数发生器产生。 进程控制块结构如下: PCB 进程标识数 链指针 优先数/轮转时间片数 占用CPU时间片数 进程所需时间片数 进程状态 进程控制块链结构如下: 其中:RUN—当前运行进程指针; HEAD—进程就绪链链首指针; TAID—进程就绪链链尾指针。 2.算法与框图 (1) 优先数法。 进程就绪链按优先数大小从高到低排列,链首进程首先投入运行。每过一个时间片,运行进程所需运行的时间片数减1,说明它已运行了一个时间片,优先数也减3,理由是该进程如果在一个时间片中完成不了,优先级应该降低一级。接着比较现行进程和就绪链链首进程的优先数,如果仍是现行进程高或者相同,就让现行进程继续进行,否则,调度就绪链链首进程投入运行。原运行进程再按其优先数大小插入就绪链,且改变它们对应的进程状态,直至所有进程都运行完各自的时间片数。 (2) 简单轮转法。 进程就绪链按各进程进入的先后次序排列,进程每次占用处理机的轮转时间按其重要程度登入进程控制块中的轮转时间片数记录项(相当于优先数法的优先数记录项位置)。每过一个时间片,运行进程占用处理机的时间片数加1,然后比较占用处理机的时间片数是否与该进程的轮转时间片数相等,若相等说明已到达轮转时间,应将现运行进程排到就绪链末尾,调度链首进程占用处理机,且改变它们的进程状态,直至所有进程完成各自的时间片。(3) 程序框图如下图所示。 广州大学学生实验报告 1、实验目的 1.1、掌握进程的概念,明确进程的含义 1.2、认识并了解并发执行的实质 2.1、掌握进程另外的创建方法 2.2、熟悉进程的睡眠、同步、撤消等进程控制方法 3.1、进一步认识并发执行的实质 3.2、分析进程竞争资源的现象,学习解决进程互斥的方法 4.1、了解守护进程 5.1、了解什么是信号 5.2、INUX系统中进程之间软中断通信的基本原理 6.1、了解什么是管道 6.2、熟悉UNIX/LINUX支持的管道通信方式 7.1、了解什么是消息 7.2、熟悉消息传送的机理 8.1、了解和熟悉共享存储机制 二、实验内容 1.1、编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统 中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示'a',子进程分别显示字符'b'和字符'c'。试观察记录屏幕上的显示结果,并分析原因。 1.2、修改上述程序,每一个进程循环显示一句话。子进程显示'daughter …'及 'son ……',父进程显示'parent ……',观察结果,分析原因。 2.1、用fork( )创建一个进程,再调用exec( )用新的程序替换该子进程的内容 2.2、利用wait( )来控制进程执行顺序 3.1、修改实验(一)中的程序2,用lockf( )来给每一个进程加锁,以实现进程之间的互斥 3.2、观察并分析出现的现象 4.1、写一个使用守护进程(daemon)的程序,来实现: 创建一个日志文件/var/log/Mydaemon.log ; 每分钟都向其中写入一个时间戳(使用time_t的格式) ; 5.1、用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按^c键);捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止: Child process1 is killed by parent! Child process2 is killed by parent! 父进程等待两个子进程终止后,输出如下的信息后终止: Parent process is killed! 5.2、用软中断通信实现进程同步的机理 操作系统实验报告(进程调度算法) 实验1 进程调度算法 一、实验内容 按优先数调度算法实现处理器调度。 二、实验目的 在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。本实验模拟在单处理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。 三、实验原理 设计一个按优先数调度算法实现处理器调度的程序。 (1) 假定系统有五个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格式为: 进程名 指针 要求运行时 间 优先数 状态 其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5。 指针——按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程中的指针为“0”。 要求运行时间——假设进程需要运行的单位时间数。 优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。 状态——可假设有两种状态,“就绪”状态和“结束”状态。五个进程的初始状态都为“就绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示。 (2) 在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。 (3) 为了调度方便,把五个进程按给定的优先数从大到小连成队列。用一单元指出队首进程,用指针指出队列的连接情况。例: 队首标志 K2 1P1 K 2 P2 K 3 P3 K 4 P4 K 5 P5 0 K4K5K3K1 2 3 1 2 4 1 5 3 4 2 R R R R R PC B1 PC B2 PC B3 PC B4 PC B5 (4) 处理器调度总是选队首进程运行。采用动态改变优先数的办法,进程每运行一次优先数就减“1”。由于本实验是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行: 优先数-1 要求运行时间-1 来模拟进程的一次运行。 提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行结束。在这里省去了这些工作。 实验题目进程的创建小组合作否姓名班级学号 一、实验目的 1、了解进程的创建。 2、了解进程间的调用以及实现。 3、分析进程竞争资源的现象,学习解决互斥的方法。 4、加深对进程概念的理解,认识并发执行的本质。 二.实验环境 Windows 系统的计算机一台,安装了Linux虚拟机 三、实验内容与步骤 1、fork()系统调用的使用例子 程序代码: #include wait(0); printf("parent process doesn't change the glob and loc:\n"); printf("glob=%d,loc=%d\n",glob,loc); exit(0); } 运行结果: 2、理解vofork()调用: 程序代码: #include 山东大学操作系统实验报告4进程同步实验 计算机科学与技术学院实验报告 实验题目:实验四、进程同步实验学号: 日期:20120409 班级:计基地12 姓名: 实验目的: 加深对并发协作进程同步与互斥概念的理解,观察和体验并发进程同步与互斥 操作的效果,分析与研究经典进程同步与互斥问题的实际解决方案。了解 Linux 系统中 IPC 进程同步工具的用法,练习并发协作进程的同步与互斥操作的编程与调试技术。 实验内容: 抽烟者问题。假设一个系统中有三个抽烟者进程,每个抽烟者不断地卷烟并抽烟。抽烟者卷起并抽掉一颗烟需要有三种材料:烟草、纸和胶水。一个抽烟者有烟草,一个有纸,另一个有胶水。系统中还有两个供应者进程,它们无限地供应所有三种材料,但每次仅轮流提供三种材料中的两种。得到缺失的两种材料的抽烟者在卷起并抽掉一颗烟后会发信号通知供应者,让它继续提供另外的两种材料。这一过程重复进行。请用以上介绍的 IPC 同步机制编程,实现该问题要求的功能。 硬件环境: 处理器:Intel? Core?i3-2350M CPU @ 2.30GHz ×4 图形:Intel? Sandybridge Mobile x86/MMX/SSE2 内存:4G 操作系统:32位 磁盘:20.1 GB 软件环境: ubuntu13.04 实验步骤: (1)新建定义了producer和consumer共用的IPC函数原型和变量的ipc.h文件。 (2)新建ipc.c文件,编写producer和consumer 共用的IPC的具体相应函数。 (3)新建Producer文件,首先定义producer 的一些行为,利用系统调用,建立共享内存区域,设定其长度并获取共享内存的首地址。然后设定生产者互斥与同步的信号灯,并为他们设置相应的初值。当有生产者进程在运行而其他生产者请求时,相应的信号灯就会阻止他,当共享内存区域已满时,信号等也会提示生产者不能再往共享内存中放入内容。 (4)新建Consumer文件,定义consumer的一些行为,利用系统调用来创建共享内存区域,并设定他的长度并获取共享内存的首地址。然后设定消费者互斥与同步的信号灯,并为他们设置相应的初值。当有消费进程在运行而其他消费者请求时,相应的信号灯就会阻止它,当共享内存区域已空时,信号等也会提示生产者不能再从共享内存中取出相应的内容。 运行的消费者应该与相应的生产者对应起来,只有这样运行结果才会正确。 一、实验目的 通过对进程调度算法的设计,深入理解进程调度的原理。 进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。 进程调度分配处理机,是控制协调进程对CPU的竞争,即按一定的调度算法从就绪队列中选中一个进程,把CPU的使用权交给被选中的进程。 进程通过定义一个进程控制块的数据结构(PCB)来表示;每个进程需要赋予进程ID、进程到达时间、进程需要运行的总时间的属性;在RR中,以1为时间片单位;运行时,输入若干个进程序列,按照时间片输出其执行序列。 二、实验环境 VC++6.0 三、实验内容 实现短进程优先调度算法(SPF)和时间片轮转调度算法(RR) [提示]: (1) 先来先服务(FCFS)调度算法 原理:每次调度是从就绪队列中,选择一个最先进入就绪队列的进程,把处理器分配给该进程,使之得到执行。该进程一旦占有了处理器,它就一直运行下去,直到该进程完成或因发生事件而阻塞,才退出处理器。 将用户作业和就绪进程按提交顺序或变为就绪状态的先后排成队列,并按照先来先服务的方式进行调度处理,是一种最普遍和最简单的方法。它优先考虑在系统中等待时间最长的作业,而不管要求运行时间的长短。 按照就绪进程进入就绪队列的先后次序进行调度,简单易实现,利于长进程,CPU繁忙型作业,不利于短进程,排队时间相对过长。 (2) 时间片轮转调度算法RR 原理:时间片轮转法主要用于进程调度。采用此算法的系统,其程序就绪队列往往按进程到达的时间来排序。进程调度按一定时间片(q)轮番运行各个进程. 进程按到达时间在就绪队列中排队,调度程序每次把CPU分配给就绪队列首进程使用一个时间片,运行完一个时间片释放CPU,排到就绪队列末尾参加下一轮调度,CPU分配给就绪队列的首进程。 固定时间片轮转法: 1 所有就绪进程按 FCFS 规则排队。 2 处理机总是分配给就绪队列的队首进程。 3 如果运行的进程用完时间片,则系统就把该进程送回就绪队列的队尾,重新排队。 4 因等待某事件而阻塞的进程送到阻塞队列。 5 系统把被唤醒的进程送到就绪队列的队尾。 可变时间片轮转法: 1 进程状态的转换方法同固定时间片轮转法。 2 响应时间固定,时间片的长短依据进程数量的多少由T = N × ( q + t )给出的关系调整。 3 根据进程优先级的高低进一步调整时间片,优先级越高的进程,分配的时间片越长。 多就绪队列轮转法: (3) 算法类型 (4)模拟程序可由两部分组成,先来先服务(FCFS)调度算法,时间片轮转。流程图如下: 广州大学学生实验报告 开课学院及实验室:计算机科学与工程实验室 2015年11月11日 实验课 操作系统成绩 程名称 实验项 进程管理与进程通信指导老师陈康民目名称 (***报告只能为文字和图片,老师评语将添加到此处,学生请勿作答***) 进程管理 (一)进程的创建实验 一、实验目的 1、掌握进程的概念,明确进程的含义 2、认识并了解并发执行的实质 二、实验内容 1、编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统中有一 个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示'a',子进程分别显示字符'b'和字符'c'。试观察记录屏幕上的显示结果,并分析原因。 2、修改上述程序,每一个进程循环显示一句话。子进程显示'daughter …'及'son ……', 父进程显示'parent ……',观察结果,分析原因。 三、实验步骤 1、编写一段程序,使用系统调用fork( )创建两个子进程。 代码: #include bca,bac, abc ,……都有可能。 2、修改上述程序,每一个进程循环显示一句话。子进程显示'daughter …'及'son ……',父进程显示'parent ……',观察结果,分析原因。 代码:#include 五邑大学实验报告 操作系统课程 2016~2017年度第1学期实验题目:进程调度 院系:计算机学院 班级: 140801 学号: 3114002472 姓名:黄凯鑫 任课教师:白明成绩评定: 实验二题目:进程调度 完成日期:2016年12 月11 日 1、实验目的 (1)设计一个有n个进程工行的进程调度程序。每个进程由一个进程控制块(PCB)表示。进程控制块通常应包含下述信息:进程名、进程优先数、进程需要运行的时间、占用CPU的时间以及进程的状态等,且可按调度算法的不同而增删。(2)调度程序应包含2~3种不同的调度算法,运行时可任意选一种,以利于各种算法的分析比较。 (3)系统应能显示或打印各进程状态和参数的变化情况,便于观察诸进程的调度过程 2、实验内容 (1)编制和调试示例给出的进程调度程序,并使其投入运行。 (2)自行设计或改写一个进程调度程序,在相应机器上调试和运行该程序,其功能应该不亚于示例。 (3)直观地评测各种调度算法的性能。 3、算法设计 算法: (1) 优先数法。 进程就绪链按优先数大小从高到低排列,链首进程首先投入运行。每过一个时间片,运行进程所需运行的时间片数减1,说明它已运行了一个时间片,优先数也减3,理由是该进程如果在一个时间片中完成不了,优先级应该降低一级。接着比较现行进程和就绪链链首进程的优先数,如果仍是现行进程高或者相同,就让现行进程继续进行,否则,调度就绪链链首进程投入运行。原运行进程再按其优先数大小插入就绪链,且改变它们对应的进程状态,直至所有进程都运行完各自的时间片数。 (2) 简单轮转法。 进程就绪链按各进程进入的先后次序排列,进程每次占用处理机的轮转时间按其重要程度登入进程控制块中的轮转时间片数记录项(相当于优先数法的优先数记录项位置)。每过一个时间片,运行进程占用处理机的时间片数加1,然后比较占用处理机的时间片数是否与该进程的轮转时间片数相等,若相等说明已到达轮转时间,应将现运行进程排到就绪链末尾,调度链首进程占用处理机,且改变它们的进程状态,直至所有进程完成各自的时间片。 实验源代码: #include 实验一进程管理 1.实验目的: (1)加深对进程概念的理解,明确进程和程序的区别; (2)进一步认识并发执行的实质; (3)分析进程争用资源的现象,学习解决进程互斥的方法; (4)了解Linux系统中进程通信的基本原理。 2.实验预备内容 (1)阅读Linux的sched.h源码文件,加深对进程管理概念的理解; (2)阅读Linux的fork()源码文件,分析进程的创建过程。 3.实验内容 (1)进程的创建: 编写一段程序,使用系统调用fork() 创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”,子进程分别显示字符“b”和“c”。试观察记录屏幕上的显示结果,并分析原因。 源代码如下: #include else{ pid2 = fork(); if(pid2<0){ fprintf(stderr,"childprocess1 failed"); exit(-1); } else if(pid2 == 0){ printf("c\n"); } else{ printf("a\n"); sleep(2); exit(0); } } return 0; } 结果如下: 分析原因: pid=fork(); 操作系统创建一个新的进程(子进程),并且在进程表中相应为它建立一个新的表项。新进程和原有进程的可执行程序是同一个程序;上下文和数据,绝大部分就是原进程(父进程)的拷贝,但它们是两个相互独立的进程!因此,这三个进程哪个先执行,哪个后执行,完全取决于操作系统的调度,没有固定的顺序。 (2)进程的控制 修改已经编写的程序,将每个进程输出一个字符改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。 将父进程的输出改为father process completed 2/11 设计性实验报告 一、实验目的 1.在Linux下用C语言编程模拟优先级进程调度算法和时间片轮转进程调度算法。 2.为了清楚地观察每个进程的调度过程,每次调度程序应将各个进程的情况显示出来。 二、总体设计(设计原理、设计方案及流程等) 1、优先级进程调度算法 采用动态优先级进程调度算法,其基本思想是每次调度总是把处理机分配给优先级最高的进程,同时在运行过程中进程的优先级随着执行或等待的时间而降低或增加。 在该实验中每个进程用一个进程控制块( PCB)表示。进程控制块包含如下信息:进程号,进程名、优先数、需要运行时间、已用CPU时间、进程状态。进程号,名字,优先数,运行的时间,事先人为地指定。每个进程的状态可以是就绪,执行,阻塞或完成4种状态之一。 就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。就绪队列中的进程在等待一个时间片后,优先级增1。如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时将进程的优先级减1,然后把它插入就绪队列等待CPU。 2、时间片轮转调度算法 采用简单时间片轮转调度算法,其基本思想是:所有就绪进程按 FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。如果运行进程用完它的时间片后还未完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。 三、实验步骤(包括主要步骤、代码分析等) 1.打开linux虚拟机,用vim编辑器打开代码进行修改和调整。用gcc编译器进行编译编译运行首先运行优先级算法,如图所示: 实验三进程的同步 一、实验目的 1、了解进程同步和互斥的概念及实现方法; 2、更深一步的了解fork()的系统调用方式。 二、实验内容 1、预习操作系统进程同步的概念及实现方法。 2、编写一段源程序,用系统调用fork()创建两个子进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。程序的输出是什么?分析原因。 3、阅读模拟火车站售票系统和实现进程的管道通信源代码,查阅有关进程创建、进程互斥、进程同步的系统功能调用或API,简要解释例程中用到的系统功能或API的用法,并编辑、编译、运行程序,记录程序的运行结果,尝试给出合理的解释。 4、(选做)修改问题2的代码,使得父子按顺序显示字符“a”;“b”、“c”编辑、编译、运行。记录程序运行结果。 三、设计思想 1、程序框架 (1)创建两个子进程:(2)售票系统: (3)管道通信: 先创建子进程,然后对内容加锁,将输出语句存入缓存,并让子进程自己进入睡眠,等待别的进程将其唤醒,最后解锁;第二个子进程也执行这样的过程。父进程等待子进程后读内容并输出。 (4)修改程序(1):在子进程的输出语句前加上sleep()语句,即等待父进程执行完以后再输出。 2、用到的文件系统调用函数 (1)创建两个子进程:fork() (2)售票系统:DWORD WINAPI Fun1Proc(LPVOID lpPartameter); CreateThread(NULL,0,Fun1Proc,NULL,0,NULL); CloseHandle(hThread1); (HANDLE)CreateMutex(NULL,FALSE,NULL); Sleep(4000)(sleep调用进程进入睡眠状态(封锁), 直到被唤醒); WaitForSingleObject(hMutex,INFINITE); ReleaseMutex(hMutex); (3)管道通信:pipe(fd),fd: int fd[2],其中: fd[0] 、fd[1]文件描述符(读、写); lockf( fd,function,byte)(fd: 文件描述符;function: 1: 锁定 0:解锁;byte: 锁定的字节数,0: 从当前位置到文件尾); write(fd,buf,byte)、read(fd,buf,byte) (fd: 文件描述符;buf : 信息传送的源(目标)地址;byte: 传送的字节数); sleep(5); exit(0); read(fd[0],s,50) (4)修改程序(1):fork(); sleep(); 四、调试过程 1、测试数据设计 (1)创建两个子进程: 操作系统实验实验二进程管理 学号 1215108019 姓名克帆 学院信息学院 班级 12电子2 实验目的 1、理解进程的概念,明确进程和程序的区别。 2、理解并发执行的实质。 3、掌握进程的创建、睡眠、撤销等进程控制方法。 实验容与要求 基本要求:用C语言编写程序,模拟实现创建新的进程;查看运行进程;换出某个进程;杀死进程等功能。 实验报告容 1、进程、进程控制块等的基本原理。 进程是现代操作系统中的一个最基本也是最重要的概念,掌握这个概念对于理解操作系统实质,分析、设计操作系统都有其非常重要的意义。为了强调进程的并发性和动态性,可以给进程作如下定义:进程是可并发执行的程序在一个数据集合上的运行过程,是系统进行资源分配和调度的一个独立单位。 进程又就绪、执行、阻塞三种基本状态,三者的变迁图如下: 由于多个程序并发执行,各程序需要轮流使用CPU,当某程序不在CPU上运行时,必须保留其被中断的程序的现场,包括:断点地址、程序状态字、通用寄存器的容、堆栈容、程序当前状态、程序的大小、运行时间等信息,以便程序再次获得CPU时,能够正确执行。为了保存这些容,需要建立—个专用数据结构,我们称这个数据结构为进程控制块PCB (Process Control Block)。 进程控制块是进程存在的惟一标志,它跟踪程序执行的情况,表明了进程在当前时刻的状态以及与其它进程和资源的关系。当创建一个进程时,实际上就是为其建立一个进程控制块。 在通常的操作系统中,PCB应包含如下一些信息: ①进程标识信息。为了标识系统中的各个进程,每个进程必须有惟一的标识名或标 识数。 ②位置信息。指出进程的程序和数据部分在存或外存中的物理位置。 ③状态信息。指出进程当前所处的状态,作为进程调度、分配CPU的依据。 ④进程的优先级。一般根据进程的轻重缓急其它信息。 这里给出的只是一般操作系统中PCB所应具有的容,不同操作系统的PCB结构是不同的,我们将在2.8节介绍Linux系统的PCB结构。 实验四:进程的管道通信 实验题目 进程的管道通信 实验目的 加深对进程概念的理解,明确进程和程序的区别。学习进程创建的过程,进一步认识进程并发执行的实质。分析进程争用资源的现象,学习解决进程互斥的方法。学习解决进程同步的方法。掌握Linux系统中进程间通过管道通信的具体实现 实验内容 使用系统调用pipe()建立一条管道,系统调用fork()分别创建两个子进程,它们分别向管道写一句话,如: Child process1 is sending a message! Child process2 is sending a message! 父进程分别从管道读出来自两个子进程的信息,显示在屏幕上。 当然,仅仅通过屏幕上输出这两句话还不能说明实现了进程的管道通信,为了能够更好的证明和显示出进程的同步互斥和通信,在其中要加入必要的跟踪条件,如一定的输出语句等,来反映程序的并发执行情况 实验要求 这是一个设计型实验,要求自行、独立编制程序。两个子进程要并发执行。实现管道的互斥使用。当一个子进程正在对管道进行写操 作时,另一个欲写入管道的子进程必须等待。使用系统调用lockf(fd[1],1,0)实现对管道的加锁操作,用lockf(fd[1],0,0)解除对管道的锁定。实现父子进程的同步,当父进程试图从一空管道中读取数据时,便进入等待状态,直到子进程将数据写入管道返回后,才将其唤醒。 为了清楚的反应进程的同步,在子进程完成相应的操作后,调用sleep()函数睡眠一段时间(程序中定为3s)。父进程先执行wait()函数,当有子进程执行完毕后,会得到子进程的返回结果并清理子进程。若子进程没执行完,父进程一直执行wait()进行监听,知道有一个子进程执行完成为僵尸进程。 程序中用到的系统调用 因为程序时在linux系统上进行编写的,所以其中要利用到相关的linux提供的系统调用。 所用到的系统调用包含在如下头文件中。 #include 计算机操作系统进程调度实验研究报告
操作系统实验报告--实验一--进程管理
操作系统进程同步实验报告
操作系统实验-进程控制
操作系统的进程调度 实验报告
操作系统实验实验1
操作系统实验报告(进程调度算法)
操作系统实验报告(进程的创建)(DOC)
山东大学操作系统实验报告4进程同步实验
操作系统原理-进程调度实验报告
操作系统实验_实验1
操作系统实验报告进程调度
操作系统-进程管理实验报告
操作系统:进程调度实验报告
进程同步实验报告
操作系统实验二
操作系统实验-进程同步与互斥